blob: 1e978ccf53900399c380b5ca0eaa4f793046204c [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 Tokiad52f4b2018-02-06 23:32:41 +000022import android.os.Parcel;
23import android.os.Parcelable;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000024import android.view.textclassifier.TextClassifier.EntityType;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +000025import android.view.textclassifier.TextClassifier.WidgetType;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000026
27import com.android.internal.util.Preconditions;
28
29import java.lang.annotation.Retention;
30import java.lang.annotation.RetentionPolicy;
31import java.util.Locale;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +000032import java.util.Objects;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000033
34/**
35 * A selection event.
36 * Specify index parameters as word token indices.
37 */
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +000038public final class SelectionEvent implements Parcelable {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000039
40 /** @hide */
41 @Retention(RetentionPolicy.SOURCE)
42 @IntDef({ACTION_OVERTYPE, ACTION_COPY, ACTION_PASTE, ACTION_CUT,
43 ACTION_SHARE, ACTION_SMART_SHARE, ACTION_DRAG, ACTION_ABANDON,
44 ACTION_OTHER, ACTION_SELECT_ALL, ACTION_RESET})
45 // NOTE: ActionType values should not be lower than 100 to avoid colliding with the other
46 // EventTypes declared below.
47 public @interface ActionType {
48 /*
49 * Terminal event types range: [100,200).
50 * Non-terminal event types range: [200,300).
51 */
52 }
53
54 /** User typed over the selection. */
55 public static final int ACTION_OVERTYPE = 100;
56 /** User copied the selection. */
57 public static final int ACTION_COPY = 101;
58 /** User pasted over the selection. */
59 public static final int ACTION_PASTE = 102;
60 /** User cut the selection. */
61 public static final int ACTION_CUT = 103;
62 /** User shared the selection. */
63 public static final int ACTION_SHARE = 104;
64 /** User clicked the textAssist menu item. */
65 public static final int ACTION_SMART_SHARE = 105;
66 /** User dragged+dropped the selection. */
67 public static final int ACTION_DRAG = 106;
68 /** User abandoned the selection. */
69 public static final int ACTION_ABANDON = 107;
70 /** User performed an action on the selection. */
71 public static final int ACTION_OTHER = 108;
72
73 // Non-terminal actions.
74 /** User activated Select All */
75 public static final int ACTION_SELECT_ALL = 200;
76 /** User reset the smart selection. */
77 public static final int ACTION_RESET = 201;
78
79 /** @hide */
80 @Retention(RetentionPolicy.SOURCE)
81 @IntDef({ACTION_OVERTYPE, ACTION_COPY, ACTION_PASTE, ACTION_CUT,
82 ACTION_SHARE, ACTION_SMART_SHARE, ACTION_DRAG, ACTION_ABANDON,
83 ACTION_OTHER, ACTION_SELECT_ALL, ACTION_RESET,
84 EVENT_SELECTION_STARTED, EVENT_SELECTION_MODIFIED,
85 EVENT_SMART_SELECTION_SINGLE, EVENT_SMART_SELECTION_MULTI,
86 EVENT_AUTO_SELECTION})
87 // NOTE: EventTypes declared here must be less than 100 to avoid colliding with the
88 // ActionTypes declared above.
89 public @interface EventType {
90 /*
91 * Range: 1 -> 99.
92 */
93 }
94
95 /** User started a new selection. */
96 public static final int EVENT_SELECTION_STARTED = 1;
97 /** User modified an existing selection. */
98 public static final int EVENT_SELECTION_MODIFIED = 2;
99 /** Smart selection triggered for a single token (word). */
100 public static final int EVENT_SMART_SELECTION_SINGLE = 3;
101 /** Smart selection triggered spanning multiple tokens (words). */
102 public static final int EVENT_SMART_SELECTION_MULTI = 4;
103 /** Something else other than User or the default TextClassifier triggered a selection. */
104 public static final int EVENT_AUTO_SELECTION = 5;
105
Jan Althaus92c6dec2018-02-02 09:20:14 +0100106 /** @hide */
107 @Retention(RetentionPolicy.SOURCE)
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000108 @IntDef({INVOCATION_MANUAL, INVOCATION_LINK, INVOCATION_UNKNOWN})
Jan Althaus92c6dec2018-02-02 09:20:14 +0100109 public @interface InvocationMethod {}
110
111 /** Selection was invoked by the user long pressing, double tapping, or dragging to select. */
112 public static final int INVOCATION_MANUAL = 1;
113 /** Selection was invoked by the user tapping on a link. */
114 public static final int INVOCATION_LINK = 2;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000115 /** Unknown invocation method */
116 public static final int INVOCATION_UNKNOWN = 0;
117
118 private static final String NO_SIGNATURE = "";
Jan Althaus92c6dec2018-02-02 09:20:14 +0100119
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000120 private final int mAbsoluteStart;
121 private final int mAbsoluteEnd;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000122 private final @EntityType String mEntityType;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000123
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000124 private @EventType int mEventType;
125 private String mPackageName = "";
126 private String mWidgetType = TextClassifier.WIDGET_TYPE_UNKNOWN;
127 private @InvocationMethod int mInvocationMethod;
128 @Nullable private String mWidgetVersion;
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100129 @Nullable private String mResultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000130 private long mEventTime;
131 private long mDurationSinceSessionStart;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000132 private long mDurationSincePreviousEvent;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000133 private int mEventIndex;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000134 @Nullable private TextClassificationSessionId mSessionId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000135 private int mStart;
136 private int mEnd;
137 private int mSmartStart;
138 private int mSmartEnd;
139
140 SelectionEvent(
141 int start, int end,
142 @EventType int eventType, @EntityType String entityType,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100143 @InvocationMethod int invocationMethod, @Nullable String resultId) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000144 Preconditions.checkArgument(end >= start, "end cannot be less than start");
145 mAbsoluteStart = start;
146 mAbsoluteEnd = end;
147 mEventType = eventType;
148 mEntityType = Preconditions.checkNotNull(entityType);
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100149 mResultId = resultId;
Jan Althaus92c6dec2018-02-02 09:20:14 +0100150 mInvocationMethod = invocationMethod;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000151 }
152
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000153 SelectionEvent(
154 int start, int end,
155 @EventType int eventType, @EntityType String entityType,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100156 @InvocationMethod int invocationMethod, @Nullable String resultId,
157 Logger.Config config) {
158 this(start, end, eventType, entityType, invocationMethod, resultId);
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000159 Preconditions.checkNotNull(config);
160 setTextClassificationSessionContext(
161 new TextClassificationContext.Builder(
162 config.getPackageName(), config.getWidgetType())
163 .setWidgetVersion(config.getWidgetVersion())
164 .build());
165 }
166
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000167 private SelectionEvent(Parcel in) {
168 mAbsoluteStart = in.readInt();
169 mAbsoluteEnd = in.readInt();
170 mEventType = in.readInt();
171 mEntityType = in.readString();
172 mWidgetVersion = in.readInt() > 0 ? in.readString() : null;
173 mPackageName = in.readString();
174 mWidgetType = in.readString();
175 mInvocationMethod = in.readInt();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100176 mResultId = in.readString();
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000177 mEventTime = in.readLong();
178 mDurationSinceSessionStart = in.readLong();
179 mDurationSincePreviousEvent = in.readLong();
180 mEventIndex = in.readInt();
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000181 mSessionId = in.readInt() > 0
182 ? TextClassificationSessionId.CREATOR.createFromParcel(in) : null;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000183 mStart = in.readInt();
184 mEnd = in.readInt();
185 mSmartStart = in.readInt();
186 mSmartEnd = in.readInt();
187 }
188
189 @Override
190 public void writeToParcel(Parcel dest, int flags) {
191 dest.writeInt(mAbsoluteStart);
192 dest.writeInt(mAbsoluteEnd);
193 dest.writeInt(mEventType);
194 dest.writeString(mEntityType);
195 dest.writeInt(mWidgetVersion != null ? 1 : 0);
196 if (mWidgetVersion != null) {
197 dest.writeString(mWidgetVersion);
198 }
199 dest.writeString(mPackageName);
200 dest.writeString(mWidgetType);
201 dest.writeInt(mInvocationMethod);
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100202 dest.writeString(mResultId);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000203 dest.writeLong(mEventTime);
204 dest.writeLong(mDurationSinceSessionStart);
205 dest.writeLong(mDurationSincePreviousEvent);
206 dest.writeInt(mEventIndex);
207 dest.writeInt(mSessionId != null ? 1 : 0);
208 if (mSessionId != null) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000209 mSessionId.writeToParcel(dest, flags);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000210 }
211 dest.writeInt(mStart);
212 dest.writeInt(mEnd);
213 dest.writeInt(mSmartStart);
214 dest.writeInt(mSmartEnd);
215 }
216
217 @Override
218 public int describeContents() {
219 return 0;
220 }
221
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000222 /**
223 * Creates a "selection started" event.
224 *
225 * @param invocationMethod the way the selection was triggered
226 * @param start the index of the selected text
227 */
228 @NonNull
229 public static SelectionEvent createSelectionStartedEvent(
230 @SelectionEvent.InvocationMethod int invocationMethod, int start) {
231 return new SelectionEvent(
232 start, start + 1, SelectionEvent.EVENT_SELECTION_STARTED,
233 TextClassifier.TYPE_UNKNOWN, invocationMethod, NO_SIGNATURE);
234 }
235
236 /**
237 * Creates a "selection modified" event.
238 * Use when the user modifies the selection.
239 *
240 * @param start the start (inclusive) index of the selection
241 * @param end the end (exclusive) index of the selection
242 *
243 * @throws IllegalArgumentException if end is less than start
244 */
245 @NonNull
246 public static SelectionEvent createSelectionModifiedEvent(int start, int end) {
247 Preconditions.checkArgument(end >= start, "end cannot be less than start");
248 return new SelectionEvent(
249 start, end, SelectionEvent.EVENT_SELECTION_MODIFIED,
250 TextClassifier.TYPE_UNKNOWN, INVOCATION_UNKNOWN, NO_SIGNATURE);
251 }
252
253 /**
254 * Creates a "selection modified" event.
255 * Use when the user modifies the selection and the selection's entity type is known.
256 *
257 * @param start the start (inclusive) index of the selection
258 * @param end the end (exclusive) index of the selection
259 * @param classification the TextClassification object returned by the TextClassifier that
260 * classified the selected text
261 *
262 * @throws IllegalArgumentException if end is less than start
263 */
264 @NonNull
265 public static SelectionEvent createSelectionModifiedEvent(
266 int start, int end, @NonNull TextClassification classification) {
267 Preconditions.checkArgument(end >= start, "end cannot be less than start");
268 Preconditions.checkNotNull(classification);
269 final String entityType = classification.getEntityCount() > 0
270 ? classification.getEntity(0)
271 : TextClassifier.TYPE_UNKNOWN;
272 return new SelectionEvent(
273 start, end, SelectionEvent.EVENT_SELECTION_MODIFIED,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100274 entityType, INVOCATION_UNKNOWN, classification.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000275 }
276
277 /**
278 * Creates a "selection modified" event.
279 * Use when a TextClassifier modifies the selection.
280 *
281 * @param start the start (inclusive) index of the selection
282 * @param end the end (exclusive) index of the selection
283 * @param selection the TextSelection object returned by the TextClassifier for the
284 * specified selection
285 *
286 * @throws IllegalArgumentException if end is less than start
287 */
288 @NonNull
289 public static SelectionEvent createSelectionModifiedEvent(
290 int start, int end, @NonNull TextSelection selection) {
291 Preconditions.checkArgument(end >= start, "end cannot be less than start");
292 Preconditions.checkNotNull(selection);
293 final String entityType = selection.getEntityCount() > 0
294 ? selection.getEntity(0)
295 : TextClassifier.TYPE_UNKNOWN;
296 return new SelectionEvent(
297 start, end, SelectionEvent.EVENT_AUTO_SELECTION,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100298 entityType, INVOCATION_UNKNOWN, selection.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000299 }
300
301 /**
302 * Creates an event specifying an action taken on a selection.
303 * Use when the user clicks on an action to act on the selected text.
304 *
305 * @param start the start (inclusive) index of the selection
306 * @param end the end (exclusive) index of the selection
307 * @param actionType the action that was performed on the selection
308 *
309 * @throws IllegalArgumentException if end is less than start
310 */
311 @NonNull
312 public static SelectionEvent createSelectionActionEvent(
313 int start, int end, @SelectionEvent.ActionType int actionType) {
314 Preconditions.checkArgument(end >= start, "end cannot be less than start");
315 checkActionType(actionType);
316 return new SelectionEvent(
317 start, end, actionType, TextClassifier.TYPE_UNKNOWN, INVOCATION_UNKNOWN,
318 NO_SIGNATURE);
319 }
320
321 /**
322 * Creates an event specifying an action taken on a selection.
323 * Use when the user clicks on an action to act on the selected text and the selection's
324 * entity type is known.
325 *
326 * @param start the start (inclusive) index of the selection
327 * @param end the end (exclusive) index of the selection
328 * @param actionType the action that was performed on the selection
329 * @param classification the TextClassification object returned by the TextClassifier that
330 * classified the selected text
331 *
332 * @throws IllegalArgumentException if end is less than start
333 * @throws IllegalArgumentException If actionType is not a valid SelectionEvent actionType
334 */
335 @NonNull
336 public static SelectionEvent createSelectionActionEvent(
337 int start, int end, @SelectionEvent.ActionType int actionType,
338 @NonNull TextClassification classification) {
339 Preconditions.checkArgument(end >= start, "end cannot be less than start");
340 Preconditions.checkNotNull(classification);
341 checkActionType(actionType);
342 final String entityType = classification.getEntityCount() > 0
343 ? classification.getEntity(0)
344 : TextClassifier.TYPE_UNKNOWN;
345 return new SelectionEvent(start, end, actionType, entityType, INVOCATION_UNKNOWN,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100346 classification.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000347 }
348
349 /**
350 * @throws IllegalArgumentException If eventType is not an {@link SelectionEvent.ActionType}
351 */
352 private static void checkActionType(@SelectionEvent.EventType int eventType)
353 throws IllegalArgumentException {
354 switch (eventType) {
355 case SelectionEvent.ACTION_OVERTYPE: // fall through
356 case SelectionEvent.ACTION_COPY: // fall through
357 case SelectionEvent.ACTION_PASTE: // fall through
358 case SelectionEvent.ACTION_CUT: // fall through
359 case SelectionEvent.ACTION_SHARE: // fall through
360 case SelectionEvent.ACTION_SMART_SHARE: // fall through
361 case SelectionEvent.ACTION_DRAG: // fall through
362 case SelectionEvent.ACTION_ABANDON: // fall through
363 case SelectionEvent.ACTION_SELECT_ALL: // fall through
364 case SelectionEvent.ACTION_RESET: // fall through
365 return;
366 default:
367 throw new IllegalArgumentException(
368 String.format(Locale.US, "%d is not an eventType", eventType));
369 }
370 }
371
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000372 int getAbsoluteStart() {
373 return mAbsoluteStart;
374 }
375
376 int getAbsoluteEnd() {
377 return mAbsoluteEnd;
378 }
379
380 /**
381 * Returns the type of event that was triggered. e.g. {@link #ACTION_COPY}.
382 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000383 @EventType
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000384 public int getEventType() {
385 return mEventType;
386 }
387
388 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000389 * Sets the event type.
390 */
391 void setEventType(@EventType int eventType) {
392 mEventType = eventType;
393 }
394
395 /**
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000396 * Returns the type of entity that is associated with this event. e.g.
397 * {@link android.view.textclassifier.TextClassifier#TYPE_EMAIL}.
398 */
399 @EntityType
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000400 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000401 public String getEntityType() {
402 return mEntityType;
403 }
404
405 /**
406 * Returns the package name of the app that this event originated in.
407 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000408 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000409 public String getPackageName() {
410 return mPackageName;
411 }
412
413 /**
414 * Returns the type of widget that was involved in triggering this event.
415 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000416 @WidgetType
417 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000418 public String getWidgetType() {
419 return mWidgetType;
420 }
421
422 /**
423 * Returns a string version info for the widget this event was triggered in.
424 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000425 @Nullable
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000426 public String getWidgetVersion() {
427 return mWidgetVersion;
428 }
429
430 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000431 * Sets the {@link TextClassificationContext} for this event.
432 */
433 void setTextClassificationSessionContext(TextClassificationContext context) {
434 mPackageName = context.getPackageName();
435 mWidgetType = context.getWidgetType();
436 mWidgetVersion = context.getWidgetVersion();
437 }
438
439 /**
Jan Althaus92c6dec2018-02-02 09:20:14 +0100440 * Returns the way the selection mode was invoked.
441 */
442 public @InvocationMethod int getInvocationMethod() {
443 return mInvocationMethod;
444 }
445
446 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000447 * Sets the invocationMethod for this event.
448 */
449 void setInvocationMethod(@InvocationMethod int invocationMethod) {
450 mInvocationMethod = invocationMethod;
451 }
452
453 /**
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100454 * Returns the id of the text classifier result associated with this event.
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000455 */
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100456 @Nullable
457 public String getResultId() {
458 return mResultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000459 }
460
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100461 SelectionEvent setResultId(@Nullable String resultId) {
462 mResultId = resultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000463 return this;
464 }
465
466 /**
467 * Returns the time this event was triggered.
468 */
469 public long getEventTime() {
470 return mEventTime;
471 }
472
473 SelectionEvent setEventTime(long timeMs) {
474 mEventTime = timeMs;
475 return this;
476 }
477
478 /**
479 * Returns the duration in ms between when this event was triggered and when the first event in
480 * the selection session was triggered.
481 */
482 public long getDurationSinceSessionStart() {
483 return mDurationSinceSessionStart;
484 }
485
486 SelectionEvent setDurationSinceSessionStart(long durationMs) {
487 mDurationSinceSessionStart = durationMs;
488 return this;
489 }
490
491 /**
492 * Returns the duration in ms between when this event was triggered and when the previous event
493 * in the selection session was triggered.
494 */
495 public long getDurationSincePreviousEvent() {
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000496 return mDurationSincePreviousEvent;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000497 }
498
499 SelectionEvent setDurationSincePreviousEvent(long durationMs) {
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000500 this.mDurationSincePreviousEvent = durationMs;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000501 return this;
502 }
503
504 /**
505 * Returns the index (e.g. 1st event, 2nd event, etc.) of this event in the selection session.
506 */
507 public int getEventIndex() {
508 return mEventIndex;
509 }
510
511 SelectionEvent setEventIndex(int index) {
512 mEventIndex = index;
513 return this;
514 }
515
516 /**
517 * Returns the selection session id.
518 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000519 @Nullable
520 public TextClassificationSessionId getSessionId() {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000521 return mSessionId;
522 }
523
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000524 SelectionEvent setSessionId(TextClassificationSessionId id) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000525 mSessionId = id;
526 return this;
527 }
528
529 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000530 * Returns the start index of this events relative to the index of the start selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000531 * event in the selection session.
532 */
533 public int getStart() {
534 return mStart;
535 }
536
537 SelectionEvent setStart(int start) {
538 mStart = start;
539 return this;
540 }
541
542 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000543 * Returns the end index of this events relative to the index of the start selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000544 * event in the selection session.
545 */
546 public int getEnd() {
547 return mEnd;
548 }
549
550 SelectionEvent setEnd(int end) {
551 mEnd = end;
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 smart selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000557 * event in the selection session.
558 */
559 public int getSmartStart() {
560 return mSmartStart;
561 }
562
563 SelectionEvent setSmartStart(int start) {
564 this.mSmartStart = start;
565 return this;
566 }
567
568 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000569 * Returns the end index of this events relative to the index of the smart selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000570 * event in the selection session.
571 */
572 public int getSmartEnd() {
573 return mSmartEnd;
574 }
575
576 SelectionEvent setSmartEnd(int end) {
577 mSmartEnd = end;
578 return this;
579 }
580
581 boolean isTerminal() {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000582 return isTerminal(mEventType);
583 }
584
585 /**
586 * Returns true if the eventType is a terminal event type. Otherwise returns false.
587 * A terminal event is an event that ends a selection interaction.
588 */
589 public static boolean isTerminal(@EventType int eventType) {
590 switch (eventType) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000591 case ACTION_OVERTYPE: // fall through
592 case ACTION_COPY: // fall through
593 case ACTION_PASTE: // fall through
594 case ACTION_CUT: // fall through
595 case ACTION_SHARE: // fall through
596 case ACTION_SMART_SHARE: // fall through
597 case ACTION_DRAG: // fall through
598 case ACTION_ABANDON: // fall through
599 case ACTION_OTHER: // fall through
600 return true;
601 default:
602 return false;
603 }
604 }
605
606 @Override
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000607 public int hashCode() {
608 return Objects.hash(mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100609 mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod, mResultId,
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000610 mEventTime, mDurationSinceSessionStart, mDurationSincePreviousEvent,
611 mEventIndex, mSessionId, mStart, mEnd, mSmartStart, mSmartEnd);
612 }
613
614 @Override
615 public boolean equals(Object obj) {
616 if (this == obj) {
617 return true;
618 }
619 if (!(obj instanceof SelectionEvent)) {
620 return false;
621 }
622
623 final SelectionEvent other = (SelectionEvent) obj;
624 return mAbsoluteStart == other.mAbsoluteStart
625 && mAbsoluteEnd == other.mAbsoluteEnd
626 && mEventType == other.mEventType
627 && Objects.equals(mEntityType, other.mEntityType)
628 && Objects.equals(mWidgetVersion, other.mWidgetVersion)
629 && Objects.equals(mPackageName, other.mPackageName)
630 && Objects.equals(mWidgetType, other.mWidgetType)
631 && mInvocationMethod == other.mInvocationMethod
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100632 && Objects.equals(mResultId, other.mResultId)
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000633 && mEventTime == other.mEventTime
634 && mDurationSinceSessionStart == other.mDurationSinceSessionStart
635 && mDurationSincePreviousEvent == other.mDurationSincePreviousEvent
636 && mEventIndex == other.mEventIndex
637 && Objects.equals(mSessionId, other.mSessionId)
638 && mStart == other.mStart
639 && mEnd == other.mEnd
640 && mSmartStart == other.mSmartStart
641 && mSmartEnd == other.mSmartEnd;
642 }
643
644 @Override
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000645 public String toString() {
646 return String.format(Locale.US,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100647 "SelectionEvent {absoluteStart=%d, absoluteEnd=%d, eventType=%d, entityType=%s, "
648 + "widgetVersion=%s, packageName=%s, widgetType=%s, invocationMethod=%s, "
649 + "resultId=%s, eventTime=%d, durationSinceSessionStart=%d, "
650 + "durationSincePreviousEvent=%d, eventIndex=%d,"
651 + "sessionId=%s, start=%d, end=%d, smartStart=%d, smartEnd=%d}",
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000652 mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100653 mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod,
654 mResultId, mEventTime, mDurationSinceSessionStart,
655 mDurationSincePreviousEvent, mEventIndex,
656 mSessionId, mStart, mEnd, mSmartStart, mSmartEnd);
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000657 }
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000658
659 public static final Creator<SelectionEvent> CREATOR = new Creator<SelectionEvent>() {
660 @Override
661 public SelectionEvent createFromParcel(Parcel in) {
662 return new SelectionEvent(in);
663 }
664
665 @Override
666 public SelectionEvent[] newArray(int size) {
667 return new SelectionEvent[size];
668 }
669 };
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100670}