blob: 09cb7a07faa8ed54d1a1f444c6e37db7e5f3d009 [file] [log] [blame]
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Abodunrinwa Tokif1d93992018-03-02 13:53:21 +000017package android.view.textclassifier;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000018
19import android.annotation.IntDef;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +000020import android.annotation.NonNull;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000021import android.annotation.Nullable;
Abodunrinwa Tokie8492692019-07-01 19:41:44 +010022import android.annotation.UserIdInt;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +000023import android.os.Parcel;
24import android.os.Parcelable;
Abodunrinwa Tokie8492692019-07-01 19:41:44 +010025import android.os.UserHandle;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000026import android.view.textclassifier.TextClassifier.EntityType;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +000027import android.view.textclassifier.TextClassifier.WidgetType;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000028
Abodunrinwa Toki52586332019-05-22 18:43:16 +010029import com.android.internal.annotations.VisibleForTesting;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000030import com.android.internal.util.Preconditions;
31
32import java.lang.annotation.Retention;
33import java.lang.annotation.RetentionPolicy;
34import java.util.Locale;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +000035import java.util.Objects;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000036
37/**
38 * A selection event.
39 * Specify index parameters as word token indices.
40 */
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +000041public final class SelectionEvent implements Parcelable {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000042
43 /** @hide */
44 @Retention(RetentionPolicy.SOURCE)
45 @IntDef({ACTION_OVERTYPE, ACTION_COPY, ACTION_PASTE, ACTION_CUT,
46 ACTION_SHARE, ACTION_SMART_SHARE, ACTION_DRAG, ACTION_ABANDON,
47 ACTION_OTHER, ACTION_SELECT_ALL, ACTION_RESET})
48 // NOTE: ActionType values should not be lower than 100 to avoid colliding with the other
49 // EventTypes declared below.
50 public @interface ActionType {
51 /*
52 * Terminal event types range: [100,200).
53 * Non-terminal event types range: [200,300).
54 */
55 }
56
57 /** User typed over the selection. */
58 public static final int ACTION_OVERTYPE = 100;
59 /** User copied the selection. */
60 public static final int ACTION_COPY = 101;
61 /** User pasted over the selection. */
62 public static final int ACTION_PASTE = 102;
63 /** User cut the selection. */
64 public static final int ACTION_CUT = 103;
65 /** User shared the selection. */
66 public static final int ACTION_SHARE = 104;
67 /** User clicked the textAssist menu item. */
68 public static final int ACTION_SMART_SHARE = 105;
69 /** User dragged+dropped the selection. */
70 public static final int ACTION_DRAG = 106;
71 /** User abandoned the selection. */
72 public static final int ACTION_ABANDON = 107;
73 /** User performed an action on the selection. */
74 public static final int ACTION_OTHER = 108;
75
76 // Non-terminal actions.
77 /** User activated Select All */
78 public static final int ACTION_SELECT_ALL = 200;
79 /** User reset the smart selection. */
80 public static final int ACTION_RESET = 201;
81
82 /** @hide */
83 @Retention(RetentionPolicy.SOURCE)
84 @IntDef({ACTION_OVERTYPE, ACTION_COPY, ACTION_PASTE, ACTION_CUT,
85 ACTION_SHARE, ACTION_SMART_SHARE, ACTION_DRAG, ACTION_ABANDON,
86 ACTION_OTHER, ACTION_SELECT_ALL, ACTION_RESET,
87 EVENT_SELECTION_STARTED, EVENT_SELECTION_MODIFIED,
88 EVENT_SMART_SELECTION_SINGLE, EVENT_SMART_SELECTION_MULTI,
89 EVENT_AUTO_SELECTION})
90 // NOTE: EventTypes declared here must be less than 100 to avoid colliding with the
91 // ActionTypes declared above.
92 public @interface EventType {
93 /*
94 * Range: 1 -> 99.
95 */
96 }
97
98 /** User started a new selection. */
99 public static final int EVENT_SELECTION_STARTED = 1;
100 /** User modified an existing selection. */
101 public static final int EVENT_SELECTION_MODIFIED = 2;
102 /** Smart selection triggered for a single token (word). */
103 public static final int EVENT_SMART_SELECTION_SINGLE = 3;
104 /** Smart selection triggered spanning multiple tokens (words). */
105 public static final int EVENT_SMART_SELECTION_MULTI = 4;
106 /** Something else other than User or the default TextClassifier triggered a selection. */
107 public static final int EVENT_AUTO_SELECTION = 5;
108
Jan Althaus92c6dec2018-02-02 09:20:14 +0100109 /** @hide */
110 @Retention(RetentionPolicy.SOURCE)
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000111 @IntDef({INVOCATION_MANUAL, INVOCATION_LINK, INVOCATION_UNKNOWN})
Jan Althaus92c6dec2018-02-02 09:20:14 +0100112 public @interface InvocationMethod {}
113
114 /** Selection was invoked by the user long pressing, double tapping, or dragging to select. */
115 public static final int INVOCATION_MANUAL = 1;
116 /** Selection was invoked by the user tapping on a link. */
117 public static final int INVOCATION_LINK = 2;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000118 /** Unknown invocation method */
119 public static final int INVOCATION_UNKNOWN = 0;
120
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100121 static final String NO_SIGNATURE = "";
Jan Althaus92c6dec2018-02-02 09:20:14 +0100122
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000123 private final int mAbsoluteStart;
124 private final int mAbsoluteEnd;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000125
Abodunrinwa Tokif9cd8132019-05-28 22:39:51 +0100126 private @EntityType String mEntityType;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000127 private @EventType int mEventType;
128 private String mPackageName = "";
129 private String mWidgetType = TextClassifier.WIDGET_TYPE_UNKNOWN;
130 private @InvocationMethod int mInvocationMethod;
131 @Nullable private String mWidgetVersion;
Abodunrinwa Tokie8492692019-07-01 19:41:44 +0100132 private @UserIdInt int mUserId = UserHandle.USER_NULL;
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100133 @Nullable private String mResultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000134 private long mEventTime;
135 private long mDurationSinceSessionStart;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000136 private long mDurationSincePreviousEvent;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000137 private int mEventIndex;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000138 @Nullable private TextClassificationSessionId mSessionId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000139 private int mStart;
140 private int mEnd;
141 private int mSmartStart;
142 private int mSmartEnd;
143
144 SelectionEvent(
145 int start, int end,
146 @EventType int eventType, @EntityType String entityType,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100147 @InvocationMethod int invocationMethod, @Nullable String resultId) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000148 Preconditions.checkArgument(end >= start, "end cannot be less than start");
149 mAbsoluteStart = start;
150 mAbsoluteEnd = end;
151 mEventType = eventType;
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000152 mEntityType = Objects.requireNonNull(entityType);
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100153 mResultId = resultId;
Jan Althaus92c6dec2018-02-02 09:20:14 +0100154 mInvocationMethod = invocationMethod;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000155 }
156
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000157 private SelectionEvent(Parcel in) {
158 mAbsoluteStart = in.readInt();
159 mAbsoluteEnd = in.readInt();
160 mEventType = in.readInt();
161 mEntityType = in.readString();
162 mWidgetVersion = in.readInt() > 0 ? in.readString() : null;
163 mPackageName = in.readString();
164 mWidgetType = in.readString();
165 mInvocationMethod = in.readInt();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100166 mResultId = in.readString();
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000167 mEventTime = in.readLong();
168 mDurationSinceSessionStart = in.readLong();
169 mDurationSincePreviousEvent = in.readLong();
170 mEventIndex = in.readInt();
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000171 mSessionId = in.readInt() > 0
172 ? TextClassificationSessionId.CREATOR.createFromParcel(in) : null;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000173 mStart = in.readInt();
174 mEnd = in.readInt();
175 mSmartStart = in.readInt();
176 mSmartEnd = in.readInt();
Tony Mak709c0a12019-12-10 07:22:23 +0000177 mUserId = in.readInt();
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000178 }
179
180 @Override
181 public void writeToParcel(Parcel dest, int flags) {
182 dest.writeInt(mAbsoluteStart);
183 dest.writeInt(mAbsoluteEnd);
184 dest.writeInt(mEventType);
185 dest.writeString(mEntityType);
186 dest.writeInt(mWidgetVersion != null ? 1 : 0);
187 if (mWidgetVersion != null) {
188 dest.writeString(mWidgetVersion);
189 }
190 dest.writeString(mPackageName);
191 dest.writeString(mWidgetType);
192 dest.writeInt(mInvocationMethod);
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100193 dest.writeString(mResultId);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000194 dest.writeLong(mEventTime);
195 dest.writeLong(mDurationSinceSessionStart);
196 dest.writeLong(mDurationSincePreviousEvent);
197 dest.writeInt(mEventIndex);
198 dest.writeInt(mSessionId != null ? 1 : 0);
199 if (mSessionId != null) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000200 mSessionId.writeToParcel(dest, flags);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000201 }
202 dest.writeInt(mStart);
203 dest.writeInt(mEnd);
204 dest.writeInt(mSmartStart);
205 dest.writeInt(mSmartEnd);
Tony Mak709c0a12019-12-10 07:22:23 +0000206 dest.writeInt(mUserId);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000207 }
208
209 @Override
210 public int describeContents() {
211 return 0;
212 }
213
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000214 /**
215 * Creates a "selection started" event.
216 *
217 * @param invocationMethod the way the selection was triggered
218 * @param start the index of the selected text
219 */
220 @NonNull
221 public static SelectionEvent createSelectionStartedEvent(
222 @SelectionEvent.InvocationMethod int invocationMethod, int start) {
223 return new SelectionEvent(
224 start, start + 1, SelectionEvent.EVENT_SELECTION_STARTED,
225 TextClassifier.TYPE_UNKNOWN, invocationMethod, NO_SIGNATURE);
226 }
227
228 /**
229 * Creates a "selection modified" event.
230 * Use when the user modifies the selection.
231 *
232 * @param start the start (inclusive) index of the selection
233 * @param end the end (exclusive) index of the selection
234 *
235 * @throws IllegalArgumentException if end is less than start
236 */
237 @NonNull
238 public static SelectionEvent createSelectionModifiedEvent(int start, int end) {
239 Preconditions.checkArgument(end >= start, "end cannot be less than start");
240 return new SelectionEvent(
241 start, end, SelectionEvent.EVENT_SELECTION_MODIFIED,
242 TextClassifier.TYPE_UNKNOWN, INVOCATION_UNKNOWN, NO_SIGNATURE);
243 }
244
245 /**
246 * Creates a "selection modified" event.
247 * Use when the user modifies the selection and the selection's entity type is known.
248 *
249 * @param start the start (inclusive) index of the selection
250 * @param end the end (exclusive) index of the selection
251 * @param classification the TextClassification object returned by the TextClassifier that
252 * classified the selected text
253 *
254 * @throws IllegalArgumentException if end is less than start
255 */
256 @NonNull
257 public static SelectionEvent createSelectionModifiedEvent(
258 int start, int end, @NonNull TextClassification classification) {
259 Preconditions.checkArgument(end >= start, "end cannot be less than start");
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000260 Objects.requireNonNull(classification);
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000261 final String entityType = classification.getEntityCount() > 0
262 ? classification.getEntity(0)
263 : TextClassifier.TYPE_UNKNOWN;
264 return new SelectionEvent(
265 start, end, SelectionEvent.EVENT_SELECTION_MODIFIED,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100266 entityType, INVOCATION_UNKNOWN, classification.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000267 }
268
269 /**
270 * Creates a "selection modified" event.
271 * Use when a TextClassifier modifies the selection.
272 *
273 * @param start the start (inclusive) index of the selection
274 * @param end the end (exclusive) index of the selection
275 * @param selection the TextSelection object returned by the TextClassifier for the
276 * specified selection
277 *
278 * @throws IllegalArgumentException if end is less than start
279 */
280 @NonNull
281 public static SelectionEvent createSelectionModifiedEvent(
282 int start, int end, @NonNull TextSelection selection) {
283 Preconditions.checkArgument(end >= start, "end cannot be less than start");
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000284 Objects.requireNonNull(selection);
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000285 final String entityType = selection.getEntityCount() > 0
286 ? selection.getEntity(0)
287 : TextClassifier.TYPE_UNKNOWN;
288 return new SelectionEvent(
289 start, end, SelectionEvent.EVENT_AUTO_SELECTION,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100290 entityType, INVOCATION_UNKNOWN, selection.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000291 }
292
293 /**
294 * Creates an event specifying an action taken on a selection.
295 * Use when the user clicks on an action to act on the selected text.
296 *
297 * @param start the start (inclusive) index of the selection
298 * @param end the end (exclusive) index of the selection
299 * @param actionType the action that was performed on the selection
300 *
301 * @throws IllegalArgumentException if end is less than start
302 */
303 @NonNull
304 public static SelectionEvent createSelectionActionEvent(
305 int start, int end, @SelectionEvent.ActionType int actionType) {
306 Preconditions.checkArgument(end >= start, "end cannot be less than start");
307 checkActionType(actionType);
308 return new SelectionEvent(
309 start, end, actionType, TextClassifier.TYPE_UNKNOWN, INVOCATION_UNKNOWN,
310 NO_SIGNATURE);
311 }
312
313 /**
314 * Creates an event specifying an action taken on a selection.
315 * Use when the user clicks on an action to act on the selected text and the selection's
316 * entity type is known.
317 *
318 * @param start the start (inclusive) index of the selection
319 * @param end the end (exclusive) index of the selection
320 * @param actionType the action that was performed on the selection
321 * @param classification the TextClassification object returned by the TextClassifier that
322 * classified the selected text
323 *
324 * @throws IllegalArgumentException if end is less than start
325 * @throws IllegalArgumentException If actionType is not a valid SelectionEvent actionType
326 */
327 @NonNull
328 public static SelectionEvent createSelectionActionEvent(
329 int start, int end, @SelectionEvent.ActionType int actionType,
330 @NonNull TextClassification classification) {
331 Preconditions.checkArgument(end >= start, "end cannot be less than start");
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000332 Objects.requireNonNull(classification);
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000333 checkActionType(actionType);
334 final String entityType = classification.getEntityCount() > 0
335 ? classification.getEntity(0)
336 : TextClassifier.TYPE_UNKNOWN;
337 return new SelectionEvent(start, end, actionType, entityType, INVOCATION_UNKNOWN,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100338 classification.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000339 }
340
341 /**
342 * @throws IllegalArgumentException If eventType is not an {@link SelectionEvent.ActionType}
343 */
344 private static void checkActionType(@SelectionEvent.EventType int eventType)
345 throws IllegalArgumentException {
346 switch (eventType) {
347 case SelectionEvent.ACTION_OVERTYPE: // fall through
348 case SelectionEvent.ACTION_COPY: // fall through
349 case SelectionEvent.ACTION_PASTE: // fall through
350 case SelectionEvent.ACTION_CUT: // fall through
351 case SelectionEvent.ACTION_SHARE: // fall through
352 case SelectionEvent.ACTION_SMART_SHARE: // fall through
353 case SelectionEvent.ACTION_DRAG: // fall through
354 case SelectionEvent.ACTION_ABANDON: // fall through
355 case SelectionEvent.ACTION_SELECT_ALL: // fall through
356 case SelectionEvent.ACTION_RESET: // fall through
Jan Althaus35b30572018-04-07 09:37:36 +0200357 case SelectionEvent.ACTION_OTHER: // fall through
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000358 return;
359 default:
360 throw new IllegalArgumentException(
361 String.format(Locale.US, "%d is not an eventType", eventType));
362 }
363 }
364
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000365 int getAbsoluteStart() {
366 return mAbsoluteStart;
367 }
368
369 int getAbsoluteEnd() {
370 return mAbsoluteEnd;
371 }
372
373 /**
374 * Returns the type of event that was triggered. e.g. {@link #ACTION_COPY}.
375 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000376 @EventType
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000377 public int getEventType() {
378 return mEventType;
379 }
380
381 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000382 * Sets the event type.
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100383 * @hide
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000384 */
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100385 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
386 public void setEventType(@EventType int eventType) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000387 mEventType = eventType;
388 }
389
390 /**
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000391 * Returns the type of entity that is associated with this event. e.g.
392 * {@link android.view.textclassifier.TextClassifier#TYPE_EMAIL}.
393 */
394 @EntityType
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000395 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000396 public String getEntityType() {
397 return mEntityType;
398 }
399
Abodunrinwa Tokif9cd8132019-05-28 22:39:51 +0100400 void setEntityType(@EntityType String entityType) {
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000401 mEntityType = Objects.requireNonNull(entityType);
Abodunrinwa Tokif9cd8132019-05-28 22:39:51 +0100402 }
403
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000404 /**
405 * Returns the package name of the app that this event originated in.
406 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000407 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000408 public String getPackageName() {
409 return mPackageName;
410 }
411
412 /**
Abodunrinwa Toki1480ed12019-07-15 16:01:51 +0100413 * Sets the id of this event's user.
414 * <p>
415 * Package-private for SystemTextClassifier's use.
416 */
417 void setUserId(@UserIdInt int userId) {
418 mUserId = userId;
419 }
420
421 /**
Abodunrinwa Tokie8492692019-07-01 19:41:44 +0100422 * Returns the id of this event's user.
423 * @hide
424 */
425 @UserIdInt
426 public int getUserId() {
427 return mUserId;
428 }
429
430 /**
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000431 * Returns the type of widget that was involved in triggering this event.
432 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000433 @WidgetType
434 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000435 public String getWidgetType() {
436 return mWidgetType;
437 }
438
439 /**
440 * Returns a string version info for the widget this event was triggered in.
441 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000442 @Nullable
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000443 public String getWidgetVersion() {
444 return mWidgetVersion;
445 }
446
447 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000448 * Sets the {@link TextClassificationContext} for this event.
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100449 * @hide
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000450 */
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100451 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
452 public void setTextClassificationSessionContext(TextClassificationContext context) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000453 mPackageName = context.getPackageName();
454 mWidgetType = context.getWidgetType();
455 mWidgetVersion = context.getWidgetVersion();
Abodunrinwa Tokie8492692019-07-01 19:41:44 +0100456 mUserId = context.getUserId();
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000457 }
458
459 /**
Jan Althaus92c6dec2018-02-02 09:20:14 +0100460 * Returns the way the selection mode was invoked.
461 */
462 public @InvocationMethod int getInvocationMethod() {
463 return mInvocationMethod;
464 }
465
466 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000467 * Sets the invocationMethod for this event.
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100468 * @hide
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000469 */
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100470 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
471 public void setInvocationMethod(@InvocationMethod int invocationMethod) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000472 mInvocationMethod = invocationMethod;
473 }
474
475 /**
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100476 * Returns the id of the text classifier result associated with this event.
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000477 */
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100478 @Nullable
479 public String getResultId() {
480 return mResultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000481 }
482
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100483 SelectionEvent setResultId(@Nullable String resultId) {
484 mResultId = resultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000485 return this;
486 }
487
488 /**
489 * Returns the time this event was triggered.
490 */
491 public long getEventTime() {
492 return mEventTime;
493 }
494
495 SelectionEvent setEventTime(long timeMs) {
496 mEventTime = timeMs;
497 return this;
498 }
499
500 /**
501 * Returns the duration in ms between when this event was triggered and when the first event in
502 * the selection session was triggered.
503 */
504 public long getDurationSinceSessionStart() {
505 return mDurationSinceSessionStart;
506 }
507
508 SelectionEvent setDurationSinceSessionStart(long durationMs) {
509 mDurationSinceSessionStart = durationMs;
510 return this;
511 }
512
513 /**
514 * Returns the duration in ms between when this event was triggered and when the previous event
515 * in the selection session was triggered.
516 */
517 public long getDurationSincePreviousEvent() {
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000518 return mDurationSincePreviousEvent;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000519 }
520
521 SelectionEvent setDurationSincePreviousEvent(long durationMs) {
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000522 this.mDurationSincePreviousEvent = durationMs;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000523 return this;
524 }
525
526 /**
527 * Returns the index (e.g. 1st event, 2nd event, etc.) of this event in the selection session.
528 */
529 public int getEventIndex() {
530 return mEventIndex;
531 }
532
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100533 /** @hide */
534 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
535 public SelectionEvent setEventIndex(int index) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000536 mEventIndex = index;
537 return this;
538 }
539
540 /**
541 * Returns the selection session id.
542 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000543 @Nullable
544 public TextClassificationSessionId getSessionId() {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000545 return mSessionId;
546 }
547
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100548 /** @hide */
549 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
550 public SelectionEvent setSessionId(@Nullable TextClassificationSessionId id) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000551 mSessionId = id;
552 return this;
553 }
554
555 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000556 * Returns the start index of this events relative to the index of the start selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000557 * event in the selection session.
558 */
559 public int getStart() {
560 return mStart;
561 }
562
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100563 /** @hide */
564 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
565 public SelectionEvent setStart(int start) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000566 mStart = start;
567 return this;
568 }
569
570 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000571 * Returns the end index of this events relative to the index of the start selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000572 * event in the selection session.
573 */
574 public int getEnd() {
575 return mEnd;
576 }
577
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100578 /** @hide */
579 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
580 public SelectionEvent setEnd(int end) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000581 mEnd = end;
582 return this;
583 }
584
585 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000586 * Returns the start index of this events relative to the index of the smart selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000587 * event in the selection session.
588 */
589 public int getSmartStart() {
590 return mSmartStart;
591 }
592
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100593 /** @hide */
594 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
595 public SelectionEvent setSmartStart(int start) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000596 this.mSmartStart = start;
597 return this;
598 }
599
600 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000601 * Returns the end index of this events relative to the index of the smart selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000602 * event in the selection session.
603 */
604 public int getSmartEnd() {
605 return mSmartEnd;
606 }
607
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100608 /** @hide */
609 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
610 public SelectionEvent setSmartEnd(int end) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000611 mSmartEnd = end;
612 return this;
613 }
614
615 boolean isTerminal() {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000616 return isTerminal(mEventType);
617 }
618
619 /**
620 * Returns true if the eventType is a terminal event type. Otherwise returns false.
621 * A terminal event is an event that ends a selection interaction.
622 */
623 public static boolean isTerminal(@EventType int eventType) {
624 switch (eventType) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000625 case ACTION_OVERTYPE: // fall through
626 case ACTION_COPY: // fall through
627 case ACTION_PASTE: // fall through
628 case ACTION_CUT: // fall through
629 case ACTION_SHARE: // fall through
630 case ACTION_SMART_SHARE: // fall through
631 case ACTION_DRAG: // fall through
632 case ACTION_ABANDON: // fall through
633 case ACTION_OTHER: // fall through
634 return true;
635 default:
636 return false;
637 }
638 }
639
640 @Override
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000641 public int hashCode() {
642 return Objects.hash(mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
Abodunrinwa Tokie8492692019-07-01 19:41:44 +0100643 mWidgetVersion, mPackageName, mUserId, mWidgetType, mInvocationMethod, mResultId,
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000644 mEventTime, mDurationSinceSessionStart, mDurationSincePreviousEvent,
645 mEventIndex, mSessionId, mStart, mEnd, mSmartStart, mSmartEnd);
646 }
647
648 @Override
649 public boolean equals(Object obj) {
650 if (this == obj) {
651 return true;
652 }
653 if (!(obj instanceof SelectionEvent)) {
654 return false;
655 }
656
657 final SelectionEvent other = (SelectionEvent) obj;
658 return mAbsoluteStart == other.mAbsoluteStart
659 && mAbsoluteEnd == other.mAbsoluteEnd
660 && mEventType == other.mEventType
661 && Objects.equals(mEntityType, other.mEntityType)
662 && Objects.equals(mWidgetVersion, other.mWidgetVersion)
663 && Objects.equals(mPackageName, other.mPackageName)
Abodunrinwa Tokie8492692019-07-01 19:41:44 +0100664 && mUserId == other.mUserId
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000665 && Objects.equals(mWidgetType, other.mWidgetType)
666 && mInvocationMethod == other.mInvocationMethod
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100667 && Objects.equals(mResultId, other.mResultId)
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000668 && mEventTime == other.mEventTime
669 && mDurationSinceSessionStart == other.mDurationSinceSessionStart
670 && mDurationSincePreviousEvent == other.mDurationSincePreviousEvent
671 && mEventIndex == other.mEventIndex
672 && Objects.equals(mSessionId, other.mSessionId)
673 && mStart == other.mStart
674 && mEnd == other.mEnd
675 && mSmartStart == other.mSmartStart
676 && mSmartEnd == other.mSmartEnd;
677 }
678
679 @Override
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000680 public String toString() {
681 return String.format(Locale.US,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100682 "SelectionEvent {absoluteStart=%d, absoluteEnd=%d, eventType=%d, entityType=%s, "
683 + "widgetVersion=%s, packageName=%s, widgetType=%s, invocationMethod=%s, "
Abodunrinwa Tokie8492692019-07-01 19:41:44 +0100684 + "userId=%d, resultId=%s, eventTime=%d, durationSinceSessionStart=%d, "
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100685 + "durationSincePreviousEvent=%d, eventIndex=%d,"
686 + "sessionId=%s, start=%d, end=%d, smartStart=%d, smartEnd=%d}",
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000687 mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100688 mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod,
Abodunrinwa Tokie8492692019-07-01 19:41:44 +0100689 mUserId, mResultId, mEventTime, mDurationSinceSessionStart,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100690 mDurationSincePreviousEvent, mEventIndex,
691 mSessionId, mStart, mEnd, mSmartStart, mSmartEnd);
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000692 }
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000693
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700694 public static final @android.annotation.NonNull Creator<SelectionEvent> CREATOR = new Creator<SelectionEvent>() {
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000695 @Override
696 public SelectionEvent createFromParcel(Parcel in) {
697 return new SelectionEvent(in);
698 }
699
700 @Override
701 public SelectionEvent[] newArray(int size) {
702 return new SelectionEvent[size];
703 }
704 };
Jan Althaus35b30572018-04-07 09:37:36 +0200705}