blob: 6f9556b6a96e911718e4fa3e045294f8d114eee5 [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
Abodunrinwa Toki52586332019-05-22 18:43:16 +010027import com.android.internal.annotations.VisibleForTesting;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000028import com.android.internal.util.Preconditions;
29
30import java.lang.annotation.Retention;
31import java.lang.annotation.RetentionPolicy;
32import java.util.Locale;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +000033import java.util.Objects;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000034
35/**
36 * A selection event.
37 * Specify index parameters as word token indices.
38 */
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +000039public final class SelectionEvent implements Parcelable {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +000040
41 /** @hide */
42 @Retention(RetentionPolicy.SOURCE)
43 @IntDef({ACTION_OVERTYPE, ACTION_COPY, ACTION_PASTE, ACTION_CUT,
44 ACTION_SHARE, ACTION_SMART_SHARE, ACTION_DRAG, ACTION_ABANDON,
45 ACTION_OTHER, ACTION_SELECT_ALL, ACTION_RESET})
46 // NOTE: ActionType values should not be lower than 100 to avoid colliding with the other
47 // EventTypes declared below.
48 public @interface ActionType {
49 /*
50 * Terminal event types range: [100,200).
51 * Non-terminal event types range: [200,300).
52 */
53 }
54
55 /** User typed over the selection. */
56 public static final int ACTION_OVERTYPE = 100;
57 /** User copied the selection. */
58 public static final int ACTION_COPY = 101;
59 /** User pasted over the selection. */
60 public static final int ACTION_PASTE = 102;
61 /** User cut the selection. */
62 public static final int ACTION_CUT = 103;
63 /** User shared the selection. */
64 public static final int ACTION_SHARE = 104;
65 /** User clicked the textAssist menu item. */
66 public static final int ACTION_SMART_SHARE = 105;
67 /** User dragged+dropped the selection. */
68 public static final int ACTION_DRAG = 106;
69 /** User abandoned the selection. */
70 public static final int ACTION_ABANDON = 107;
71 /** User performed an action on the selection. */
72 public static final int ACTION_OTHER = 108;
73
74 // Non-terminal actions.
75 /** User activated Select All */
76 public static final int ACTION_SELECT_ALL = 200;
77 /** User reset the smart selection. */
78 public static final int ACTION_RESET = 201;
79
80 /** @hide */
81 @Retention(RetentionPolicy.SOURCE)
82 @IntDef({ACTION_OVERTYPE, ACTION_COPY, ACTION_PASTE, ACTION_CUT,
83 ACTION_SHARE, ACTION_SMART_SHARE, ACTION_DRAG, ACTION_ABANDON,
84 ACTION_OTHER, ACTION_SELECT_ALL, ACTION_RESET,
85 EVENT_SELECTION_STARTED, EVENT_SELECTION_MODIFIED,
86 EVENT_SMART_SELECTION_SINGLE, EVENT_SMART_SELECTION_MULTI,
87 EVENT_AUTO_SELECTION})
88 // NOTE: EventTypes declared here must be less than 100 to avoid colliding with the
89 // ActionTypes declared above.
90 public @interface EventType {
91 /*
92 * Range: 1 -> 99.
93 */
94 }
95
96 /** User started a new selection. */
97 public static final int EVENT_SELECTION_STARTED = 1;
98 /** User modified an existing selection. */
99 public static final int EVENT_SELECTION_MODIFIED = 2;
100 /** Smart selection triggered for a single token (word). */
101 public static final int EVENT_SMART_SELECTION_SINGLE = 3;
102 /** Smart selection triggered spanning multiple tokens (words). */
103 public static final int EVENT_SMART_SELECTION_MULTI = 4;
104 /** Something else other than User or the default TextClassifier triggered a selection. */
105 public static final int EVENT_AUTO_SELECTION = 5;
106
Jan Althaus92c6dec2018-02-02 09:20:14 +0100107 /** @hide */
108 @Retention(RetentionPolicy.SOURCE)
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000109 @IntDef({INVOCATION_MANUAL, INVOCATION_LINK, INVOCATION_UNKNOWN})
Jan Althaus92c6dec2018-02-02 09:20:14 +0100110 public @interface InvocationMethod {}
111
112 /** Selection was invoked by the user long pressing, double tapping, or dragging to select. */
113 public static final int INVOCATION_MANUAL = 1;
114 /** Selection was invoked by the user tapping on a link. */
115 public static final int INVOCATION_LINK = 2;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000116 /** Unknown invocation method */
117 public static final int INVOCATION_UNKNOWN = 0;
118
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100119 static final String NO_SIGNATURE = "";
Jan Althaus92c6dec2018-02-02 09:20:14 +0100120
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000121 private final int mAbsoluteStart;
122 private final int mAbsoluteEnd;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000123
Abodunrinwa Tokif9cd8132019-05-28 22:39:51 +0100124 private @EntityType String mEntityType;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000125 private @EventType int mEventType;
126 private String mPackageName = "";
127 private String mWidgetType = TextClassifier.WIDGET_TYPE_UNKNOWN;
128 private @InvocationMethod int mInvocationMethod;
129 @Nullable private String mWidgetVersion;
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100130 @Nullable private String mResultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000131 private long mEventTime;
132 private long mDurationSinceSessionStart;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000133 private long mDurationSincePreviousEvent;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000134 private int mEventIndex;
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000135 @Nullable private TextClassificationSessionId mSessionId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000136 private int mStart;
137 private int mEnd;
138 private int mSmartStart;
139 private int mSmartEnd;
Joanne Chung97d3a452020-03-04 19:03:11 +0800140 @Nullable private SystemTextClassifierMetadata mSystemTcMetadata;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000141
142 SelectionEvent(
143 int start, int end,
144 @EventType int eventType, @EntityType String entityType,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100145 @InvocationMethod int invocationMethod, @Nullable String resultId) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000146 Preconditions.checkArgument(end >= start, "end cannot be less than start");
147 mAbsoluteStart = start;
148 mAbsoluteEnd = end;
149 mEventType = eventType;
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000150 mEntityType = Objects.requireNonNull(entityType);
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100151 mResultId = resultId;
Jan Althaus92c6dec2018-02-02 09:20:14 +0100152 mInvocationMethod = invocationMethod;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000153 }
154
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000155 private SelectionEvent(Parcel in) {
156 mAbsoluteStart = in.readInt();
157 mAbsoluteEnd = in.readInt();
158 mEventType = in.readInt();
159 mEntityType = in.readString();
160 mWidgetVersion = in.readInt() > 0 ? in.readString() : null;
161 mPackageName = in.readString();
162 mWidgetType = in.readString();
163 mInvocationMethod = in.readInt();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100164 mResultId = in.readString();
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000165 mEventTime = in.readLong();
166 mDurationSinceSessionStart = in.readLong();
167 mDurationSincePreviousEvent = in.readLong();
168 mEventIndex = in.readInt();
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000169 mSessionId = in.readInt() > 0
170 ? TextClassificationSessionId.CREATOR.createFromParcel(in) : null;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000171 mStart = in.readInt();
172 mEnd = in.readInt();
173 mSmartStart = in.readInt();
174 mSmartEnd = in.readInt();
Joanne Chung97d3a452020-03-04 19:03:11 +0800175 mSystemTcMetadata = in.readParcelable(null);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000176 }
177
178 @Override
179 public void writeToParcel(Parcel dest, int flags) {
180 dest.writeInt(mAbsoluteStart);
181 dest.writeInt(mAbsoluteEnd);
182 dest.writeInt(mEventType);
183 dest.writeString(mEntityType);
184 dest.writeInt(mWidgetVersion != null ? 1 : 0);
185 if (mWidgetVersion != null) {
186 dest.writeString(mWidgetVersion);
187 }
188 dest.writeString(mPackageName);
189 dest.writeString(mWidgetType);
190 dest.writeInt(mInvocationMethod);
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100191 dest.writeString(mResultId);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000192 dest.writeLong(mEventTime);
193 dest.writeLong(mDurationSinceSessionStart);
194 dest.writeLong(mDurationSincePreviousEvent);
195 dest.writeInt(mEventIndex);
196 dest.writeInt(mSessionId != null ? 1 : 0);
197 if (mSessionId != null) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000198 mSessionId.writeToParcel(dest, flags);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000199 }
200 dest.writeInt(mStart);
201 dest.writeInt(mEnd);
202 dest.writeInt(mSmartStart);
203 dest.writeInt(mSmartEnd);
Joanne Chung97d3a452020-03-04 19:03:11 +0800204 dest.writeParcelable(mSystemTcMetadata, flags);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000205 }
206
207 @Override
208 public int describeContents() {
209 return 0;
210 }
211
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000212 /**
213 * Creates a "selection started" event.
214 *
215 * @param invocationMethod the way the selection was triggered
216 * @param start the index of the selected text
217 */
218 @NonNull
219 public static SelectionEvent createSelectionStartedEvent(
220 @SelectionEvent.InvocationMethod int invocationMethod, int start) {
221 return new SelectionEvent(
222 start, start + 1, SelectionEvent.EVENT_SELECTION_STARTED,
223 TextClassifier.TYPE_UNKNOWN, invocationMethod, NO_SIGNATURE);
224 }
225
226 /**
227 * Creates a "selection modified" event.
228 * Use when the user modifies the selection.
229 *
230 * @param start the start (inclusive) index of the selection
231 * @param end the end (exclusive) index of the selection
232 *
233 * @throws IllegalArgumentException if end is less than start
234 */
235 @NonNull
236 public static SelectionEvent createSelectionModifiedEvent(int start, int end) {
237 Preconditions.checkArgument(end >= start, "end cannot be less than start");
238 return new SelectionEvent(
239 start, end, SelectionEvent.EVENT_SELECTION_MODIFIED,
240 TextClassifier.TYPE_UNKNOWN, INVOCATION_UNKNOWN, NO_SIGNATURE);
241 }
242
243 /**
244 * Creates a "selection modified" event.
245 * Use when the user modifies the selection and the selection's entity type is known.
246 *
247 * @param start the start (inclusive) index of the selection
248 * @param end the end (exclusive) index of the selection
249 * @param classification the TextClassification object returned by the TextClassifier that
250 * classified the selected text
251 *
252 * @throws IllegalArgumentException if end is less than start
253 */
254 @NonNull
255 public static SelectionEvent createSelectionModifiedEvent(
256 int start, int end, @NonNull TextClassification classification) {
257 Preconditions.checkArgument(end >= start, "end cannot be less than start");
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000258 Objects.requireNonNull(classification);
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000259 final String entityType = classification.getEntityCount() > 0
260 ? classification.getEntity(0)
261 : TextClassifier.TYPE_UNKNOWN;
262 return new SelectionEvent(
263 start, end, SelectionEvent.EVENT_SELECTION_MODIFIED,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100264 entityType, INVOCATION_UNKNOWN, classification.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000265 }
266
267 /**
268 * Creates a "selection modified" event.
269 * Use when a TextClassifier modifies the selection.
270 *
271 * @param start the start (inclusive) index of the selection
272 * @param end the end (exclusive) index of the selection
273 * @param selection the TextSelection object returned by the TextClassifier for the
274 * specified selection
275 *
276 * @throws IllegalArgumentException if end is less than start
277 */
278 @NonNull
279 public static SelectionEvent createSelectionModifiedEvent(
280 int start, int end, @NonNull TextSelection selection) {
281 Preconditions.checkArgument(end >= start, "end cannot be less than start");
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000282 Objects.requireNonNull(selection);
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000283 final String entityType = selection.getEntityCount() > 0
284 ? selection.getEntity(0)
285 : TextClassifier.TYPE_UNKNOWN;
286 return new SelectionEvent(
287 start, end, SelectionEvent.EVENT_AUTO_SELECTION,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100288 entityType, INVOCATION_UNKNOWN, selection.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000289 }
290
291 /**
292 * Creates an event specifying an action taken on a selection.
293 * Use when the user clicks on an action to act on the selected text.
294 *
295 * @param start the start (inclusive) index of the selection
296 * @param end the end (exclusive) index of the selection
297 * @param actionType the action that was performed on the selection
298 *
299 * @throws IllegalArgumentException if end is less than start
300 */
301 @NonNull
302 public static SelectionEvent createSelectionActionEvent(
303 int start, int end, @SelectionEvent.ActionType int actionType) {
304 Preconditions.checkArgument(end >= start, "end cannot be less than start");
305 checkActionType(actionType);
306 return new SelectionEvent(
307 start, end, actionType, TextClassifier.TYPE_UNKNOWN, INVOCATION_UNKNOWN,
308 NO_SIGNATURE);
309 }
310
311 /**
312 * Creates an event specifying an action taken on a selection.
313 * Use when the user clicks on an action to act on the selected text and the selection's
314 * entity type is known.
315 *
316 * @param start the start (inclusive) index of the selection
317 * @param end the end (exclusive) index of the selection
318 * @param actionType the action that was performed on the selection
319 * @param classification the TextClassification object returned by the TextClassifier that
320 * classified the selected text
321 *
322 * @throws IllegalArgumentException if end is less than start
323 * @throws IllegalArgumentException If actionType is not a valid SelectionEvent actionType
324 */
325 @NonNull
326 public static SelectionEvent createSelectionActionEvent(
327 int start, int end, @SelectionEvent.ActionType int actionType,
328 @NonNull TextClassification classification) {
329 Preconditions.checkArgument(end >= start, "end cannot be less than start");
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000330 Objects.requireNonNull(classification);
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000331 checkActionType(actionType);
332 final String entityType = classification.getEntityCount() > 0
333 ? classification.getEntity(0)
334 : TextClassifier.TYPE_UNKNOWN;
335 return new SelectionEvent(start, end, actionType, entityType, INVOCATION_UNKNOWN,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100336 classification.getId());
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000337 }
338
339 /**
340 * @throws IllegalArgumentException If eventType is not an {@link SelectionEvent.ActionType}
341 */
342 private static void checkActionType(@SelectionEvent.EventType int eventType)
343 throws IllegalArgumentException {
344 switch (eventType) {
345 case SelectionEvent.ACTION_OVERTYPE: // fall through
346 case SelectionEvent.ACTION_COPY: // fall through
347 case SelectionEvent.ACTION_PASTE: // fall through
348 case SelectionEvent.ACTION_CUT: // fall through
349 case SelectionEvent.ACTION_SHARE: // fall through
350 case SelectionEvent.ACTION_SMART_SHARE: // fall through
351 case SelectionEvent.ACTION_DRAG: // fall through
352 case SelectionEvent.ACTION_ABANDON: // fall through
353 case SelectionEvent.ACTION_SELECT_ALL: // fall through
354 case SelectionEvent.ACTION_RESET: // fall through
Jan Althaus35b30572018-04-07 09:37:36 +0200355 case SelectionEvent.ACTION_OTHER: // fall through
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000356 return;
357 default:
358 throw new IllegalArgumentException(
359 String.format(Locale.US, "%d is not an eventType", eventType));
360 }
361 }
362
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000363 int getAbsoluteStart() {
364 return mAbsoluteStart;
365 }
366
367 int getAbsoluteEnd() {
368 return mAbsoluteEnd;
369 }
370
371 /**
372 * Returns the type of event that was triggered. e.g. {@link #ACTION_COPY}.
373 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000374 @EventType
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000375 public int getEventType() {
376 return mEventType;
377 }
378
379 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000380 * Sets the event type.
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100381 * @hide
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000382 */
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100383 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
384 public void setEventType(@EventType int eventType) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000385 mEventType = eventType;
386 }
387
388 /**
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000389 * Returns the type of entity that is associated with this event. e.g.
390 * {@link android.view.textclassifier.TextClassifier#TYPE_EMAIL}.
391 */
392 @EntityType
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000393 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000394 public String getEntityType() {
395 return mEntityType;
396 }
397
Abodunrinwa Tokif9cd8132019-05-28 22:39:51 +0100398 void setEntityType(@EntityType String entityType) {
Daulet Zhanguzine1559472019-12-18 14:17:56 +0000399 mEntityType = Objects.requireNonNull(entityType);
Abodunrinwa Tokif9cd8132019-05-28 22:39:51 +0100400 }
401
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000402 /**
403 * Returns the package name of the app that this event originated in.
404 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000405 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000406 public String getPackageName() {
Tony Mak293bdf32020-02-18 11:33:43 +0000407 return mPackageName;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000408 }
409
410 /**
Joanne Chung97d3a452020-03-04 19:03:11 +0800411 * Sets the information about the {@link SystemTextClassifier} that sent this request.
Tony Makc5a74322020-02-04 17:18:15 +0000412 *
413 * @hide
414 */
Joanne Chung97d3a452020-03-04 19:03:11 +0800415 void setSystemTextClassifierMetadata(@Nullable SystemTextClassifierMetadata systemTcMetadata) {
416 mSystemTcMetadata = systemTcMetadata;
Tony Makc5a74322020-02-04 17:18:15 +0000417 }
418
419 /**
Joanne Chung97d3a452020-03-04 19:03:11 +0800420 * Returns the information about the {@link SystemTextClassifier} that sent this request.
Tony Makc5a74322020-02-04 17:18:15 +0000421 *
422 * @hide
423 */
Joanne Chung97d3a452020-03-04 19:03:11 +0800424 @Nullable
425 public SystemTextClassifierMetadata getSystemTextClassifierMetadata() {
426 return mSystemTcMetadata;
Tony Makc5a74322020-02-04 17:18:15 +0000427 }
428
429 /**
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000430 * Returns the type of widget that was involved in triggering this event.
431 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000432 @WidgetType
433 @NonNull
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000434 public String getWidgetType() {
435 return mWidgetType;
436 }
437
438 /**
439 * Returns a string version info for the widget this event was triggered in.
440 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000441 @Nullable
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000442 public String getWidgetVersion() {
443 return mWidgetVersion;
444 }
445
446 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000447 * Sets the {@link TextClassificationContext} for this event.
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100448 * @hide
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000449 */
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100450 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
451 public void setTextClassificationSessionContext(TextClassificationContext context) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000452 mPackageName = context.getPackageName();
453 mWidgetType = context.getWidgetType();
454 mWidgetVersion = context.getWidgetVersion();
Joanne Chung97d3a452020-03-04 19:03:11 +0800455 mSystemTcMetadata = context.getSystemTextClassifierMetadata();
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000456 }
457
458 /**
Jan Althaus92c6dec2018-02-02 09:20:14 +0100459 * Returns the way the selection mode was invoked.
460 */
461 public @InvocationMethod int getInvocationMethod() {
462 return mInvocationMethod;
463 }
464
465 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000466 * Sets the invocationMethod for this event.
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100467 * @hide
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000468 */
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100469 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
470 public void setInvocationMethod(@InvocationMethod int invocationMethod) {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000471 mInvocationMethod = invocationMethod;
472 }
473
474 /**
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100475 * Returns the id of the text classifier result associated with this event.
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000476 */
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100477 @Nullable
478 public String getResultId() {
479 return mResultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000480 }
481
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100482 SelectionEvent setResultId(@Nullable String resultId) {
483 mResultId = resultId;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000484 return this;
485 }
486
487 /**
488 * Returns the time this event was triggered.
489 */
490 public long getEventTime() {
491 return mEventTime;
492 }
493
494 SelectionEvent setEventTime(long timeMs) {
495 mEventTime = timeMs;
496 return this;
497 }
498
499 /**
500 * Returns the duration in ms between when this event was triggered and when the first event in
501 * the selection session was triggered.
502 */
503 public long getDurationSinceSessionStart() {
504 return mDurationSinceSessionStart;
505 }
506
507 SelectionEvent setDurationSinceSessionStart(long durationMs) {
508 mDurationSinceSessionStart = durationMs;
509 return this;
510 }
511
512 /**
513 * Returns the duration in ms between when this event was triggered and when the previous event
514 * in the selection session was triggered.
515 */
516 public long getDurationSincePreviousEvent() {
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000517 return mDurationSincePreviousEvent;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000518 }
519
520 SelectionEvent setDurationSincePreviousEvent(long durationMs) {
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000521 this.mDurationSincePreviousEvent = durationMs;
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000522 return this;
523 }
524
525 /**
526 * Returns the index (e.g. 1st event, 2nd event, etc.) of this event in the selection session.
527 */
528 public int getEventIndex() {
529 return mEventIndex;
530 }
531
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100532 /** @hide */
533 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
534 public SelectionEvent setEventIndex(int index) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000535 mEventIndex = index;
536 return this;
537 }
538
539 /**
540 * Returns the selection session id.
541 */
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000542 @Nullable
543 public TextClassificationSessionId getSessionId() {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000544 return mSessionId;
545 }
546
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100547 /** @hide */
548 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
549 public SelectionEvent setSessionId(@Nullable TextClassificationSessionId id) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000550 mSessionId = id;
551 return this;
552 }
553
554 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000555 * Returns the start index of this events relative to the index of the start selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000556 * event in the selection session.
557 */
558 public int getStart() {
559 return mStart;
560 }
561
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100562 /** @hide */
563 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
564 public SelectionEvent setStart(int start) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000565 mStart = start;
566 return this;
567 }
568
569 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000570 * Returns the end index of this events relative to the index of the start selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000571 * event in the selection session.
572 */
573 public int getEnd() {
574 return mEnd;
575 }
576
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100577 /** @hide */
578 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
579 public SelectionEvent setEnd(int end) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000580 mEnd = end;
581 return this;
582 }
583
584 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000585 * Returns the start index of this events relative to the index of the smart selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000586 * event in the selection session.
587 */
588 public int getSmartStart() {
589 return mSmartStart;
590 }
591
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100592 /** @hide */
593 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
594 public SelectionEvent setSmartStart(int start) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000595 this.mSmartStart = start;
596 return this;
597 }
598
599 /**
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000600 * Returns the end index of this events relative to the index of the smart selection
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000601 * event in the selection session.
602 */
603 public int getSmartEnd() {
604 return mSmartEnd;
605 }
606
Abodunrinwa Toki52586332019-05-22 18:43:16 +0100607 /** @hide */
608 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
609 public SelectionEvent setSmartEnd(int end) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000610 mSmartEnd = end;
611 return this;
612 }
613
614 boolean isTerminal() {
Abodunrinwa Toki88be5a62018-03-23 04:01:28 +0000615 return isTerminal(mEventType);
616 }
617
618 /**
619 * Returns true if the eventType is a terminal event type. Otherwise returns false.
620 * A terminal event is an event that ends a selection interaction.
621 */
622 public static boolean isTerminal(@EventType int eventType) {
623 switch (eventType) {
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000624 case ACTION_OVERTYPE: // fall through
625 case ACTION_COPY: // fall through
626 case ACTION_PASTE: // fall through
627 case ACTION_CUT: // fall through
628 case ACTION_SHARE: // fall through
629 case ACTION_SMART_SHARE: // fall through
630 case ACTION_DRAG: // fall through
631 case ACTION_ABANDON: // fall through
632 case ACTION_OTHER: // fall through
633 return true;
634 default:
635 return false;
636 }
637 }
638
639 @Override
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000640 public int hashCode() {
641 return Objects.hash(mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
Joanne Chung97d3a452020-03-04 19:03:11 +0800642 mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod, mResultId,
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000643 mEventTime, mDurationSinceSessionStart, mDurationSincePreviousEvent,
Joanne Chung97d3a452020-03-04 19:03:11 +0800644 mEventIndex, mSessionId, mStart, mEnd, mSmartStart, mSmartEnd, mSystemTcMetadata);
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000645 }
646
647 @Override
648 public boolean equals(Object obj) {
649 if (this == obj) {
650 return true;
651 }
652 if (!(obj instanceof SelectionEvent)) {
653 return false;
654 }
655
656 final SelectionEvent other = (SelectionEvent) obj;
657 return mAbsoluteStart == other.mAbsoluteStart
658 && mAbsoluteEnd == other.mAbsoluteEnd
659 && mEventType == other.mEventType
660 && Objects.equals(mEntityType, other.mEntityType)
661 && Objects.equals(mWidgetVersion, other.mWidgetVersion)
662 && Objects.equals(mPackageName, other.mPackageName)
663 && Objects.equals(mWidgetType, other.mWidgetType)
664 && mInvocationMethod == other.mInvocationMethod
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100665 && Objects.equals(mResultId, other.mResultId)
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000666 && mEventTime == other.mEventTime
667 && mDurationSinceSessionStart == other.mDurationSinceSessionStart
668 && mDurationSincePreviousEvent == other.mDurationSincePreviousEvent
669 && mEventIndex == other.mEventIndex
670 && Objects.equals(mSessionId, other.mSessionId)
671 && mStart == other.mStart
672 && mEnd == other.mEnd
673 && mSmartStart == other.mSmartStart
Tony Makc5a74322020-02-04 17:18:15 +0000674 && mSmartEnd == other.mSmartEnd
Joanne Chung97d3a452020-03-04 19:03:11 +0800675 && mSystemTcMetadata == other.mSystemTcMetadata;
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000676 }
677
678 @Override
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000679 public String toString() {
680 return String.format(Locale.US,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100681 "SelectionEvent {absoluteStart=%d, absoluteEnd=%d, eventType=%d, entityType=%s, "
682 + "widgetVersion=%s, packageName=%s, widgetType=%s, invocationMethod=%s, "
Joanne Chung97d3a452020-03-04 19:03:11 +0800683 + "resultId=%s, eventTime=%d, durationSinceSessionStart=%d, "
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100684 + "durationSincePreviousEvent=%d, eventIndex=%d,"
Tony Makc5a74322020-02-04 17:18:15 +0000685 + "sessionId=%s, start=%d, end=%d, smartStart=%d, smartEnd=%d, "
Joanne Chung97d3a452020-03-04 19:03:11 +0800686 + "systemTcMetadata=%s}",
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000687 mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100688 mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod,
Joanne Chung97d3a452020-03-04 19:03:11 +0800689 mResultId, mEventTime, mDurationSinceSessionStart, mDurationSincePreviousEvent,
690 mEventIndex, mSessionId, mStart, mEnd, mSmartStart, mSmartEnd, mSystemTcMetadata);
Abodunrinwa Toki3bb44362017-12-05 07:33:41 +0000691 }
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000692
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700693 public static final @android.annotation.NonNull Creator<SelectionEvent> CREATOR = new Creator<SelectionEvent>() {
Abodunrinwa Tokiad52f4b2018-02-06 23:32:41 +0000694 @Override
695 public SelectionEvent createFromParcel(Parcel in) {
696 return new SelectionEvent(in);
697 }
698
699 @Override
700 public SelectionEvent[] newArray(int size) {
701 return new SelectionEvent[size];
702 }
703 };
Jan Althaus35b30572018-04-07 09:37:36 +0200704}