• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package com.android.textclassifier.common.logging;
18 
19 import android.os.Bundle;
20 import androidx.annotation.IntDef;
21 import com.google.common.base.Preconditions;
22 import com.google.errorprone.annotations.CanIgnoreReturnValue;
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 import java.util.Arrays;
26 import java.util.Locale;
27 import javax.annotation.Nonnull;
28 import javax.annotation.Nullable;
29 
30 /**
31  * This class represents events that are sent by components to a TextClassifier to report something
32  * of note that relates to a feature powered by the TextClassifier. The TextClassifier may log these
33  * events or use them to improve future responses to queries.
34  *
35  * <p>Each category of events has its their own subclass. Events of each type have an associated set
36  * of related properties. You can find their specification in the subclasses.
37  */
38 public abstract class TextClassifierEvent {
39 
40   /** Category of the event */
41   @Retention(RetentionPolicy.SOURCE)
42   @IntDef({
43     CATEGORY_SELECTION,
44     CATEGORY_LINKIFY,
45     CATEGORY_CONVERSATION_ACTIONS,
46     CATEGORY_LANGUAGE_DETECTION
47   })
48   public @interface Category {
49     // For custom event categories, use range 1000+.
50   }
51 
52   /**
53    * Smart selection
54    *
55    * @see TextSelectionEvent
56    */
57   public static final int CATEGORY_SELECTION = 1;
58   /**
59    * Linkify
60    *
61    * @see TextLinkifyEvent
62    */
63   public static final int CATEGORY_LINKIFY = 2;
64   /**
65    * Conversation actions
66    *
67    * @see ConversationActionsEvent
68    */
69   public static final int CATEGORY_CONVERSATION_ACTIONS = 3;
70   /**
71    * Language detection
72    *
73    * @see LanguageDetectionEvent
74    */
75   public static final int CATEGORY_LANGUAGE_DETECTION = 4;
76 
77   /** Type of the event */
78   @Retention(RetentionPolicy.SOURCE)
79   @IntDef({
80     TYPE_SELECTION_STARTED,
81     TYPE_SELECTION_MODIFIED,
82     TYPE_SMART_SELECTION_SINGLE,
83     TYPE_SMART_SELECTION_MULTI,
84     TYPE_AUTO_SELECTION,
85     TYPE_ACTIONS_SHOWN,
86     TYPE_LINK_CLICKED,
87     TYPE_OVERTYPE,
88     TYPE_COPY_ACTION,
89     TYPE_PASTE_ACTION,
90     TYPE_CUT_ACTION,
91     TYPE_SHARE_ACTION,
92     TYPE_SMART_ACTION,
93     TYPE_SELECTION_DRAG,
94     TYPE_SELECTION_DESTROYED,
95     TYPE_OTHER_ACTION,
96     TYPE_SELECT_ALL,
97     TYPE_SELECTION_RESET,
98     TYPE_MANUAL_REPLY,
99     TYPE_ACTIONS_GENERATED,
100     TYPE_LINKS_GENERATED
101   })
102   public @interface Type {
103     // For custom event types, use range 1,000,000+.
104   }
105 
106   // All these event type constants are required to match with those defined in
107   // textclassifier_enums.proto.
108   /** User started a new selection. */
109   public static final int TYPE_SELECTION_STARTED = 1;
110   /** User modified an existing selection. */
111   public static final int TYPE_SELECTION_MODIFIED = 2;
112   /** Smart selection triggered for a single token (word). */
113   public static final int TYPE_SMART_SELECTION_SINGLE = 3;
114   /** Smart selection triggered spanning multiple tokens (words). */
115   public static final int TYPE_SMART_SELECTION_MULTI = 4;
116   /** Something else other than user or the default TextClassifier triggered a selection. */
117   public static final int TYPE_AUTO_SELECTION = 5;
118   /** Smart actions shown to the user. */
119   public static final int TYPE_ACTIONS_SHOWN = 6;
120   /** User clicked a link. */
121   public static final int TYPE_LINK_CLICKED = 7;
122   /** User typed over the selection. */
123   public static final int TYPE_OVERTYPE = 8;
124   /** User clicked on Copy action. */
125   public static final int TYPE_COPY_ACTION = 9;
126   /** User clicked on Paste action. */
127   public static final int TYPE_PASTE_ACTION = 10;
128   /** User clicked on Cut action. */
129   public static final int TYPE_CUT_ACTION = 11;
130   /** User clicked on Share action. */
131   public static final int TYPE_SHARE_ACTION = 12;
132   /** User clicked on a Smart action. */
133   public static final int TYPE_SMART_ACTION = 13;
134   /** User dragged+dropped the selection. */
135   public static final int TYPE_SELECTION_DRAG = 14;
136   /** Selection is destroyed. */
137   public static final int TYPE_SELECTION_DESTROYED = 15;
138   /** User clicked on a custom action. */
139   public static final int TYPE_OTHER_ACTION = 16;
140   /** User clicked on Select All action */
141   public static final int TYPE_SELECT_ALL = 17;
142   /** User reset the smart selection. */
143   public static final int TYPE_SELECTION_RESET = 18;
144   /** User composed a reply. */
145   public static final int TYPE_MANUAL_REPLY = 19;
146   /** TextClassifier generated some actions */
147   public static final int TYPE_ACTIONS_GENERATED = 20;
148   /** Some text links were generated. */
149   public static final int TYPE_LINKS_GENERATED = 21;
150 
151   @Category private final int eventCategory;
152   @Type private final int eventType;
153   @Nullable private final String[] entityTypes;
154   @Nullable private TextClassificationContext eventContext;
155   @Nullable private final String resultId;
156   private final int eventIndex;
157   private final float[] scores;
158   @Nullable private final String modelName;
159   private final int[] actionIndices;
160   @Nullable private final Locale locale;
161   private final Bundle extras;
162 
TextClassifierEvent(Builder<?> builder)163   private TextClassifierEvent(Builder<?> builder) {
164     eventCategory = builder.eventCategory;
165     eventType = builder.eventType;
166     entityTypes = builder.entityTypes;
167     eventContext = builder.eventContext;
168     resultId = builder.resultId;
169     eventIndex = builder.eventIndex;
170     scores = builder.scores;
171     modelName = builder.modelName;
172     actionIndices = builder.actionIndices;
173     locale = builder.locale;
174     extras = builder.extras == null ? Bundle.EMPTY : builder.extras;
175   }
176 
177   /** Returns the event category. e.g. {@link #CATEGORY_SELECTION}. */
178   @Category
getEventCategory()179   public int getEventCategory() {
180     return eventCategory;
181   }
182 
183   /** Returns the event type. e.g. {@link #TYPE_SELECTION_STARTED}. */
184   @Type
getEventType()185   public int getEventType() {
186     return eventType;
187   }
188 
189   /**
190    * Returns an array of entity types. e.g. {@link TextClassifier#TYPE_ADDRESS}.
191    *
192    * @see Builder#setEntityTypes(String...) for supported types.
193    */
194   @Nonnull
getEntityTypes()195   public String[] getEntityTypes() {
196     return entityTypes;
197   }
198 
199   /** Returns the event context. */
200   @Nullable
getEventContext()201   public TextClassificationContext getEventContext() {
202     return eventContext;
203   }
204 
205   /**
206    * Sets the event context.
207    *
208    * <p>Package-private for SystemTextClassifier's use.
209    */
setEventContext(@ullable TextClassificationContext eventContext)210   void setEventContext(@Nullable TextClassificationContext eventContext) {
211     this.eventContext = eventContext;
212   }
213 
214   /** Returns the id of the text classifier result related to this event. */
215   @Nullable
getResultId()216   public String getResultId() {
217     return resultId;
218   }
219 
220   /** Returns the index of this event in the series of event it belongs to. */
getEventIndex()221   public int getEventIndex() {
222     return eventIndex;
223   }
224 
225   /** Returns the scores of the suggestions. */
getScores()226   public float[] getScores() {
227     return scores;
228   }
229 
230   /** Returns the model name. */
231   @Nullable
getModelName()232   public String getModelName() {
233     return modelName;
234   }
235 
236   /**
237    * Returns the indices of the actions relating to this event. Actions are usually returned by the
238    * text classifier in priority order with the most preferred action at index 0. This list gives an
239    * indication of the position of the actions that are being reported.
240    *
241    * @see Builder#setActionIndices(int...)
242    */
getActionIndices()243   public int[] getActionIndices() {
244     return actionIndices;
245   }
246 
247   /** Returns the detected locale. */
248   @Nullable
getLocale()249   public Locale getLocale() {
250     return locale;
251   }
252 
253   /**
254    * Returns a bundle containing non-structured extra information about this event.
255    *
256    * <p><b>NOTE: </b>Do not modify this bundle.
257    */
258   @Nonnull
getExtras()259   public Bundle getExtras() {
260     return extras;
261   }
262 
263   @Override
toString()264   public String toString() {
265     StringBuilder out = new StringBuilder(128);
266     out.append(this.getClass().getSimpleName());
267     out.append("{");
268     out.append("mEventCategory=").append(eventCategory);
269     out.append(", mEventType=").append(eventType);
270     out.append(", mEntityTypes=").append(Arrays.toString(entityTypes));
271     out.append(", mEventContext=").append(eventContext);
272     out.append(", mResultId=").append(resultId);
273     out.append(", mEventIndex=").append(eventIndex);
274     out.append(", mExtras=").append(extras);
275     out.append(", mScores=").append(Arrays.toString(scores));
276     out.append(", mModelName=").append(modelName);
277     out.append(", mActionIndices=").append(Arrays.toString(actionIndices));
278     toString(out);
279     out.append("}");
280     return out.toString();
281   }
282 
283   /**
284    * Overrides this to append extra fields to the output of {@link #toString()}.
285    *
286    * <p>Extra fields should be formatted like this: ", {field_name}={field_value}".
287    */
toString(StringBuilder out)288   void toString(StringBuilder out) {}
289 
290   /**
291    * Builder to build a text classifier event.
292    *
293    * @param <T> The subclass to be built.
294    */
295   public abstract static class Builder<T extends Builder<T>> {
296 
297     private final int eventCategory;
298     private final int eventType;
299     private String[] entityTypes = new String[0];
300     @Nullable private TextClassificationContext eventContext;
301     @Nullable private String resultId;
302     private int eventIndex;
303     private float[] scores = new float[0];
304     @Nullable private String modelName;
305     private int[] actionIndices = new int[0];
306     @Nullable private Locale locale;
307     @Nullable private Bundle extras;
308 
309     /**
310      * Creates a builder for building {@link TextClassifierEvent}s.
311      *
312      * @param eventCategory The event category. e.g. {@link #CATEGORY_SELECTION}
313      * @param eventType The event type. e.g. {@link #TYPE_SELECTION_STARTED}
314      */
Builder(@ategory int eventCategory, @Type int eventType)315     private Builder(@Category int eventCategory, @Type int eventType) {
316       this.eventCategory = eventCategory;
317       this.eventType = eventType;
318     }
319 
320     /**
321      * Sets the entity types. e.g. {@link android.view.textclassifier.TextClassifier#TYPE_ADDRESS}.
322      *
323      * <p>Supported types:
324      *
325      * <p>See {@link android.view.textclassifier.TextClassifier.EntityType}
326      *
327      * <p>See {@link android.view.textclassifier.ConversationAction.ActionType}
328      *
329      * <p>See {@link Locale#toLanguageTag()}
330      */
331     @CanIgnoreReturnValue
setEntityTypes(String... entityTypes)332     public T setEntityTypes(String... entityTypes) {
333       Preconditions.checkNotNull(entityTypes);
334       this.entityTypes = new String[entityTypes.length];
335       System.arraycopy(entityTypes, 0, this.entityTypes, 0, entityTypes.length);
336       return self();
337     }
338 
339     /** Sets the event context. */
340     @CanIgnoreReturnValue
setEventContext(@ullable TextClassificationContext eventContext)341     public T setEventContext(@Nullable TextClassificationContext eventContext) {
342       this.eventContext = eventContext;
343       return self();
344     }
345 
346     /** Sets the id of the text classifier result related to this event. */
347     @CanIgnoreReturnValue
348     @Nonnull
setResultId(@ullable String resultId)349     public T setResultId(@Nullable String resultId) {
350       this.resultId = resultId;
351       return self();
352     }
353 
354     /** Sets the index of this event in the series of events it belongs to. */
355     @CanIgnoreReturnValue
356     @Nonnull
setEventIndex(int eventIndex)357     public T setEventIndex(int eventIndex) {
358       this.eventIndex = eventIndex;
359       return self();
360     }
361 
362     /** Sets the scores of the suggestions. */
363     @CanIgnoreReturnValue
364     @Nonnull
setScores(@onnull float... scores)365     public T setScores(@Nonnull float... scores) {
366       Preconditions.checkNotNull(scores);
367       this.scores = new float[scores.length];
368       System.arraycopy(scores, 0, this.scores, 0, scores.length);
369       return self();
370     }
371 
372     /** Sets the model name string. */
373     @CanIgnoreReturnValue
374     @Nonnull
setModelName(@ullable String modelVersion)375     public T setModelName(@Nullable String modelVersion) {
376       modelName = modelVersion;
377       return self();
378     }
379 
380     /**
381      * Sets the indices of the actions involved in this event. Actions are usually returned by the
382      * text classifier in priority order with the most preferred action at index 0. These indices
383      * give an indication of the position of the actions that are being reported.
384      *
385      * <p>E.g.
386      *
387      * <pre>
388      *   // 3 smart actions are shown at index 0, 1, 2 respectively in response to a link click.
389      *   new TextClassifierEvent.Builder(CATEGORY_LINKIFY, TYPE_ACTIONS_SHOWN)
390      *       .setEventIndex(0, 1, 2)
391      *       ...
392      *       .build();
393      *
394      *   ...
395      *
396      *   // Smart action at index 1 is activated.
397      *   new TextClassifierEvent.Builder(CATEGORY_LINKIFY, TYPE_SMART_ACTION)
398      *       .setEventIndex(1)
399      *       ...
400      *       .build();
401      * </pre>
402      *
403      * @see android.view.textclassifier.TextClassification#getActions()
404      */
405     @CanIgnoreReturnValue
406     @Nonnull
setActionIndices(@onnull int... actionIndices)407     public T setActionIndices(@Nonnull int... actionIndices) {
408       this.actionIndices = new int[actionIndices.length];
409       System.arraycopy(actionIndices, 0, this.actionIndices, 0, actionIndices.length);
410       return self();
411     }
412 
413     /** Sets the detected locale. */
414     @CanIgnoreReturnValue
415     @Nonnull
setLocale(@ullable Locale locale)416     public T setLocale(@Nullable Locale locale) {
417       this.locale = locale;
418       return self();
419     }
420 
421     /**
422      * Sets a bundle containing non-structured extra information about the event.
423      *
424      * <p><b>NOTE: </b>Prefer to set only immutable values on the bundle otherwise, avoid updating
425      * the internals of this bundle as it may have unexpected consequences on the clients of the
426      * built event object. For similar reasons, avoid depending on mutable objects in this bundle.
427      */
428     @CanIgnoreReturnValue
429     @Nonnull
setExtras(@onnull Bundle extras)430     public T setExtras(@Nonnull Bundle extras) {
431       this.extras = Preconditions.checkNotNull(extras);
432       return self();
433     }
434 
self()435     abstract T self();
436   }
437 
438   /**
439    * This class represents events that are related to the smart text selection feature.
440    *
441    * <p>
442    *
443    * <pre>
444    *     // User started a selection. e.g. "York" in text "New York City, NY".
445    *     new TextSelectionEvent.Builder(TYPE_SELECTION_STARTED)
446    *         .setEventContext(classificationContext)
447    *         .setEventIndex(0)
448    *         .build();
449    *
450    *     // System smart-selects a recognized entity. e.g. "New York City".
451    *     new TextSelectionEvent.Builder(TYPE_SMART_SELECTION_MULTI)
452    *         .setEventContext(classificationContext)
453    *         .setResultId(textSelection.getId())
454    *         .setRelativeWordStartIndex(-1) // Goes back one word to "New" from "York".
455    *         .setRelativeWordEndIndex(2)    // Goes forward 2 words from "York" to start of ",".
456    *         .setEntityTypes(textClassification.getEntity(0))
457    *         .setScore(textClassification.getConfidenceScore(entityType))
458    *         .setEventIndex(1)
459    *         .build();
460    *
461    *     // User resets the selection to the original selection. i.e. "York".
462    *     new TextSelectionEvent.Builder(TYPE_SELECTION_RESET)
463    *         .setEventContext(classificationContext)
464    *         .setResultId(textSelection.getId())
465    *         .setRelativeSuggestedWordStartIndex(-1) // Repeated from above.
466    *         .setRelativeSuggestedWordEndIndex(2)    // Repeated from above.
467    *         .setRelativeWordStartIndex(0)           // Original selection is always at (0, 1].
468    *         .setRelativeWordEndIndex(1)
469    *         .setEntityTypes(textClassification.getEntity(0))
470    *         .setScore(textClassification.getConfidenceScore(entityType))
471    *         .setEventIndex(2)
472    *         .build();
473    *
474    *     // User modified the selection. e.g. "New".
475    *     new TextSelectionEvent.Builder(TYPE_SELECTION_MODIFIED)
476    *         .setEventContext(classificationContext)
477    *         .setResultId(textSelection.getId())
478    *         .setRelativeSuggestedWordStartIndex(-1) // Repeated from above.
479    *         .setRelativeSuggestedWordEndIndex(2)    // Repeated from above.
480    *         .setRelativeWordStartIndex(-1)          // Goes backward one word from "York" to
481    *         "New".
482    *         .setRelativeWordEndIndex(0)             // Goes backward one word to exclude "York".
483    *         .setEntityTypes(textClassification.getEntity(0))
484    *         .setScore(textClassification.getConfidenceScore(entityType))
485    *         .setEventIndex(3)
486    *         .build();
487    *
488    *     // Smart (contextual) actions (at indices, 0, 1, 2) presented to the user.
489    *     // e.g. "Map", "Ride share", "Explore".
490    *     new TextSelectionEvent.Builder(TYPE_ACTIONS_SHOWN)
491    *         .setEventContext(classificationContext)
492    *         .setResultId(textClassification.getId())
493    *         .setEntityTypes(textClassification.getEntity(0))
494    *         .setScore(textClassification.getConfidenceScore(entityType))
495    *         .setActionIndices(0, 1, 2)
496    *         .setEventIndex(4)
497    *         .build();
498    *
499    *     // User chooses the "Copy" action.
500    *     new TextSelectionEvent.Builder(TYPE_COPY_ACTION)
501    *         .setEventContext(classificationContext)
502    *         .setResultId(textClassification.getId())
503    *         .setEntityTypes(textClassification.getEntity(0))
504    *         .setScore(textClassification.getConfidenceScore(entityType))
505    *         .setEventIndex(5)
506    *         .build();
507    *
508    *     // User chooses smart action at index 1. i.e. "Ride share".
509    *     new TextSelectionEvent.Builder(TYPE_SMART_ACTION)
510    *         .setEventContext(classificationContext)
511    *         .setResultId(textClassification.getId())
512    *         .setEntityTypes(textClassification.getEntity(0))
513    *         .setScore(textClassification.getConfidenceScore(entityType))
514    *         .setActionIndices(1)
515    *         .setEventIndex(5)
516    *         .build();
517    *
518    *     // Selection dismissed.
519    *     new TextSelectionEvent.Builder(TYPE_SELECTION_DESTROYED)
520    *         .setEventContext(classificationContext)
521    *         .setResultId(textClassification.getId())
522    *         .setEntityTypes(textClassification.getEntity(0))
523    *         .setScore(textClassification.getConfidenceScore(entityType))
524    *         .setEventIndex(6)
525    *         .build();
526    * </pre>
527    *
528    * <p>
529    */
530   public static final class TextSelectionEvent extends TextClassifierEvent {
531 
532     final int relativeWordStartIndex;
533     final int relativeWordEndIndex;
534     final int relativeSuggestedWordStartIndex;
535     final int relativeSuggestedWordEndIndex;
536 
TextSelectionEvent(TextSelectionEvent.Builder builder)537     private TextSelectionEvent(TextSelectionEvent.Builder builder) {
538       super(builder);
539       relativeWordStartIndex = builder.relativeWordStartIndex;
540       relativeWordEndIndex = builder.relativeWordEndIndex;
541       relativeSuggestedWordStartIndex = builder.relativeSuggestedWordStartIndex;
542       relativeSuggestedWordEndIndex = builder.relativeSuggestedWordEndIndex;
543     }
544 
545     /** Returns the relative word index of the start of the selection. */
getRelativeWordStartIndex()546     public int getRelativeWordStartIndex() {
547       return relativeWordStartIndex;
548     }
549 
550     /** Returns the relative word (exclusive) index of the end of the selection. */
getRelativeWordEndIndex()551     public int getRelativeWordEndIndex() {
552       return relativeWordEndIndex;
553     }
554 
555     /** Returns the relative word index of the start of the smart selection. */
getRelativeSuggestedWordStartIndex()556     public int getRelativeSuggestedWordStartIndex() {
557       return relativeSuggestedWordStartIndex;
558     }
559 
560     /** Returns the relative word (exclusive) index of the end of the smart selection. */
getRelativeSuggestedWordEndIndex()561     public int getRelativeSuggestedWordEndIndex() {
562       return relativeSuggestedWordEndIndex;
563     }
564 
565     @Override
toString(StringBuilder out)566     void toString(StringBuilder out) {
567       out.append(", getRelativeWordStartIndex=").append(relativeWordStartIndex);
568       out.append(", getRelativeWordEndIndex=").append(relativeWordEndIndex);
569       out.append(", getRelativeSuggestedWordStartIndex=").append(relativeSuggestedWordStartIndex);
570       out.append(", getRelativeSuggestedWordEndIndex=").append(relativeSuggestedWordEndIndex);
571     }
572 
573     /** Builder class for {@link TextSelectionEvent}. */
574     public static final class Builder
575         extends TextClassifierEvent.Builder<TextSelectionEvent.Builder> {
576       int relativeWordStartIndex;
577       int relativeWordEndIndex;
578       int relativeSuggestedWordStartIndex;
579       int relativeSuggestedWordEndIndex;
580 
581       /**
582        * Creates a builder for building {@link TextSelectionEvent}s.
583        *
584        * @param eventType The event type. e.g. {@link #TYPE_SELECTION_STARTED}
585        */
Builder(@ype int eventType)586       public Builder(@Type int eventType) {
587         super(CATEGORY_SELECTION, eventType);
588       }
589 
590       /** Sets the relative word index of the start of the selection. */
591       @CanIgnoreReturnValue
592       @Nonnull
setRelativeWordStartIndex(int relativeWordStartIndex)593       public Builder setRelativeWordStartIndex(int relativeWordStartIndex) {
594         this.relativeWordStartIndex = relativeWordStartIndex;
595         return this;
596       }
597 
598       /** Sets the relative word (exclusive) index of the end of the selection. */
599       @CanIgnoreReturnValue
600       @Nonnull
setRelativeWordEndIndex(int relativeWordEndIndex)601       public Builder setRelativeWordEndIndex(int relativeWordEndIndex) {
602         this.relativeWordEndIndex = relativeWordEndIndex;
603         return this;
604       }
605 
606       /** Sets the relative word index of the start of the smart selection. */
607       @CanIgnoreReturnValue
608       @Nonnull
setRelativeSuggestedWordStartIndex(int relativeSuggestedWordStartIndex)609       public Builder setRelativeSuggestedWordStartIndex(int relativeSuggestedWordStartIndex) {
610         this.relativeSuggestedWordStartIndex = relativeSuggestedWordStartIndex;
611         return this;
612       }
613 
614       /** Sets the relative word (exclusive) index of the end of the smart selection. */
615       @CanIgnoreReturnValue
616       @Nonnull
setRelativeSuggestedWordEndIndex(int relativeSuggestedWordEndIndex)617       public Builder setRelativeSuggestedWordEndIndex(int relativeSuggestedWordEndIndex) {
618         this.relativeSuggestedWordEndIndex = relativeSuggestedWordEndIndex;
619         return this;
620       }
621 
622       @Override
self()623       TextSelectionEvent.Builder self() {
624         return this;
625       }
626 
627       /** Builds and returns a {@link TextSelectionEvent}. */
628       @Nonnull
build()629       public TextSelectionEvent build() {
630         return new TextSelectionEvent(this);
631       }
632     }
633   }
634 
635   /**
636    * This class represents events that are related to the smart linkify feature.
637    *
638    * <p>
639    *
640    * <pre>
641    *     // User clicked on a link.
642    *     new TextLinkifyEvent.Builder(TYPE_LINK_CLICKED)
643    *         .setEventContext(classificationContext)
644    *         .setResultId(textClassification.getId())
645    *         .setEntityTypes(textClassification.getEntity(0))
646    *         .setScore(textClassification.getConfidenceScore(entityType))
647    *         .setEventIndex(0)
648    *         .build();
649    *
650    *     // Smart (contextual) actions presented to the user in response to a link click.
651    *     new TextLinkifyEvent.Builder(TYPE_ACTIONS_SHOWN)
652    *         .setEventContext(classificationContext)
653    *         .setResultId(textClassification.getId())
654    *         .setEntityTypes(textClassification.getEntity(0))
655    *         .setScore(textClassification.getConfidenceScore(entityType))
656    *         .setActionIndices(range(textClassification.getActions().size()))
657    *         .setEventIndex(1)
658    *         .build();
659    *
660    *     // User chooses smart action at index 0.
661    *     new TextLinkifyEvent.Builder(TYPE_SMART_ACTION)
662    *         .setEventContext(classificationContext)
663    *         .setResultId(textClassification.getId())
664    *         .setEntityTypes(textClassification.getEntity(0))
665    *         .setScore(textClassification.getConfidenceScore(entityType))
666    *         .setActionIndices(0)
667    *         .setEventIndex(2)
668    *         .build();
669    * </pre>
670    */
671   public static final class TextLinkifyEvent extends TextClassifierEvent {
672 
TextLinkifyEvent(TextLinkifyEvent.Builder builder)673     private TextLinkifyEvent(TextLinkifyEvent.Builder builder) {
674       super(builder);
675     }
676 
677     /** Builder class for {@link TextLinkifyEvent}. */
678     public static final class Builder
679         extends TextClassifierEvent.Builder<TextLinkifyEvent.Builder> {
680       /**
681        * Creates a builder for building {@link TextLinkifyEvent}s.
682        *
683        * @param eventType The event type. e.g. {@link #TYPE_SMART_ACTION}
684        */
Builder(@ype int eventType)685       public Builder(@Type int eventType) {
686         super(TextClassifierEvent.CATEGORY_LINKIFY, eventType);
687       }
688 
689       @Override
self()690       Builder self() {
691         return this;
692       }
693 
694       /** Builds and returns a {@link TextLinkifyEvent}. */
695       @Nonnull
build()696       public TextLinkifyEvent build() {
697         return new TextLinkifyEvent(this);
698       }
699     }
700   }
701 
702   /**
703    * This class represents events that are related to the language detection feature.
704    * <p>
705    * <pre>
706    *     // Translate action shown for foreign text.
707    *     new LanguageDetectionEvent.Builder(TYPE_ACTIONS_SHOWN)
708    *         .setEventContext(classificationContext)
709    *         .setResultId(textClassification.getId())
710    *         .setEntityTypes(language)
711    *         .setScore(score)
712    *         .setActionIndices(textClassification.getActions().indexOf(translateAction))
713    *         .setEventIndex(0)
714    *         .build();
715    *
716    *     // Translate action selected.
717    *     new LanguageDetectionEvent.Builder(TYPE_SMART_ACTION)
718    *         .setEventContext(classificationContext)
719    *         .setResultId(textClassification.getId())
720    *         .setEntityTypes(language)
721    *         .setScore(score)
722    *         .setActionIndices(textClassification.getActions().indexOf(translateAction))
723    *         .setEventIndex(1)
724    *         .build();
725    */
726   public static final class LanguageDetectionEvent extends TextClassifierEvent {
727 
LanguageDetectionEvent(LanguageDetectionEvent.Builder builder)728     private LanguageDetectionEvent(LanguageDetectionEvent.Builder builder) {
729       super(builder);
730     }
731 
732     /** Builder class for {@link LanguageDetectionEvent}. */
733     public static final class Builder
734         extends TextClassifierEvent.Builder<LanguageDetectionEvent.Builder> {
735 
736       /**
737        * Creates a builder for building {@link TextSelectionEvent}s.
738        *
739        * @param eventType The event type. e.g. {@link #TYPE_SMART_ACTION}
740        */
Builder(@ype int eventType)741       public Builder(@Type int eventType) {
742         super(TextClassifierEvent.CATEGORY_LANGUAGE_DETECTION, eventType);
743       }
744 
745       @Override
self()746       Builder self() {
747         return this;
748       }
749 
750       /** Builds and returns a {@link LanguageDetectionEvent}. */
751       @Nonnull
build()752       public LanguageDetectionEvent build() {
753         return new LanguageDetectionEvent(this);
754       }
755     }
756   }
757 
758   /**
759    * This class represents events that are related to the conversation actions feature.
760    *
761    * <p>
762    *
763    * <pre>
764    *     // Conversation (contextual) actions/replies generated.
765    *     new ConversationActionsEvent.Builder(TYPE_ACTIONS_GENERATED)
766    *         .setEventContext(classificationContext)
767    *         .setResultId(conversationActions.getId())
768    *         .setEntityTypes(getTypes(conversationActions))
769    *         .setActionIndices(range(conversationActions.getActions().size()))
770    *         .setEventIndex(0)
771    *         .build();
772    *
773    *     // Conversation actions/replies presented to user.
774    *     new ConversationActionsEvent.Builder(TYPE_ACTIONS_SHOWN)
775    *         .setEventContext(classificationContext)
776    *         .setResultId(conversationActions.getId())
777    *         .setEntityTypes(getTypes(conversationActions))
778    *         .setActionIndices(range(conversationActions.getActions().size()))
779    *         .setEventIndex(1)
780    *         .build();
781    *
782    *     // User clicked the "Reply" button to compose their custom reply.
783    *     new ConversationActionsEvent.Builder(TYPE_MANUAL_REPLY)
784    *         .setEventContext(classificationContext)
785    *         .setResultId(conversationActions.getId())
786    *         .setEventIndex(2)
787    *         .build();
788    *
789    *     // User selected a smart (contextual) action/reply.
790    *     new ConversationActionsEvent.Builder(TYPE_SMART_ACTION)
791    *         .setEventContext(classificationContext)
792    *         .setResultId(conversationActions.getId())
793    *         .setEntityTypes(conversationActions.get(1).getType())
794    *         .setScore(conversationAction.get(1).getConfidenceScore())
795    *         .setActionIndices(1)
796    *         .setEventIndex(2)
797    *         .build();
798    * </pre>
799    */
800   public static final class ConversationActionsEvent extends TextClassifierEvent {
801 
ConversationActionsEvent(ConversationActionsEvent.Builder builder)802     private ConversationActionsEvent(ConversationActionsEvent.Builder builder) {
803       super(builder);
804     }
805 
806     /** Builder class for {@link ConversationActionsEvent}. */
807     public static final class Builder
808         extends TextClassifierEvent.Builder<ConversationActionsEvent.Builder> {
809       /**
810        * Creates a builder for building {@link TextSelectionEvent}s.
811        *
812        * @param eventType The event type. e.g. {@link #TYPE_SMART_ACTION}
813        */
Builder(@ype int eventType)814       public Builder(@Type int eventType) {
815         super(TextClassifierEvent.CATEGORY_CONVERSATION_ACTIONS, eventType);
816       }
817 
818       @Override
self()819       Builder self() {
820         return this;
821       }
822 
823       /** Builds and returns a {@link ConversationActionsEvent}. */
824       @Nonnull
build()825       public ConversationActionsEvent build() {
826         return new ConversationActionsEvent(this);
827       }
828     }
829   }
830 }
831