• 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 androidx.textclassifier;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 
22 import androidx.annotation.IntDef;
23 import androidx.annotation.RestrictTo;
24 import androidx.annotation.StringDef;
25 import androidx.collection.ArraySet;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.List;
34 
35 /**
36  * Interface for providing text classification related features.
37  *
38  * TextClassifier acts as a proxy to either the system provided TextClassifier, or an equivalent
39  * implementation provided by an app. Each instance of the class therefore represents one connection
40  * to the classifier implementation.
41  *
42  * <p>Unless otherwise stated, methods of this interface are blocking operations.
43  * Avoid calling them on the UI thread.
44  */
45 public class TextClassifier {
46 
47     // TODO: describe in the class documentation how a TC implementation in chosen/located.
48 
49     /** Signifies that the TextClassifier did not identify an entity. */
50     public static final String TYPE_UNKNOWN = "";
51     /** Signifies that the classifier ran, but didn't recognize a know entity. */
52     public static final String TYPE_OTHER = "other";
53     /** Identifies an e-mail address. */
54     public static final String TYPE_EMAIL = "email";
55     /** Identifies a phone number. */
56     public static final String TYPE_PHONE = "phone";
57     /** Identifies a physical address. */
58     public static final String TYPE_ADDRESS = "address";
59     /** Identifies a URL. */
60     public static final String TYPE_URL = "url";
61 
62     /** @hide */
63     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
64     @Retention(RetentionPolicy.SOURCE)
65     @StringDef(value = {
66             TYPE_UNKNOWN,
67             TYPE_OTHER,
68             TYPE_EMAIL,
69             TYPE_PHONE,
70             TYPE_ADDRESS,
71             TYPE_URL,
72     })
73     @interface EntityType {}
74 
75     /** Designates that the TextClassifier should identify all entity types it can. **/
76     static final int ENTITY_PRESET_ALL = 0;
77     /** Designates that the TextClassifier should identify no entities. **/
78     static final int ENTITY_PRESET_NONE = 1;
79     /** Designates that the TextClassifier should identify a base set of entities determined by the
80      * TextClassifier. **/
81     static final int ENTITY_PRESET_BASE = 2;
82 
83     /** @hide */
84     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
85     @Retention(RetentionPolicy.SOURCE)
86     @IntDef(value = {ENTITY_PRESET_ALL, ENTITY_PRESET_NONE, ENTITY_PRESET_BASE})
87     @interface EntityPreset {}
88 
89     // TODO: add constructor, suggestSelection, classifyText, generateLinks, logEvent
90 
91     /**
92      * Returns a {@link Collection} of the entity types in the specified preset.
93      *
94      * @see #ENTITY_PRESET_ALL
95      * @see #ENTITY_PRESET_NONE
96      */
getEntitiesForPreset(@ntityPreset int entityPreset)97     /* package */ Collection<String> getEntitiesForPreset(@EntityPreset int entityPreset) {
98         // TODO: forward call to the classifier implementation.
99         return Collections.EMPTY_LIST;
100     }
101 
102     /**
103      * Configuration object for specifying what entities to identify.
104      *
105      * Configs are initially based on a predefined preset, and can be modified from there.
106      */
107     static final class EntityConfig implements Parcelable {
108         private final @EntityPreset int mEntityPreset;
109         private final Collection<String> mExcludedEntityTypes;
110         private final Collection<String> mIncludedEntityTypes;
111 
EntityConfig(@ntityPreset int mEntityPreset)112         EntityConfig(@EntityPreset int mEntityPreset) {
113             this.mEntityPreset = mEntityPreset;
114             mExcludedEntityTypes = new ArraySet<>();
115             mIncludedEntityTypes = new ArraySet<>();
116         }
117 
118         /**
119          * Specifies an entity to include in addition to any specified by the enity preset.
120          *
121          * Note that if an entity has been excluded, the exclusion will take precedence.
122          */
includeEntities(String... entities)123         public EntityConfig includeEntities(String... entities) {
124             mIncludedEntityTypes.addAll(Arrays.asList(entities));
125             return this;
126         }
127 
128         /**
129          * Specifies an entity to be excluded.
130          */
excludeEntities(String... entities)131         public EntityConfig excludeEntities(String... entities) {
132             mExcludedEntityTypes.addAll(Arrays.asList(entities));
133             return this;
134         }
135 
136         /**
137          * Returns an unmodifiable list of the final set of entities to find.
138          */
getEntities(TextClassifier textClassifier)139         public List<String> getEntities(TextClassifier textClassifier) {
140             ArrayList<String> entities = new ArrayList<>();
141             for (String entity : textClassifier.getEntitiesForPreset(mEntityPreset)) {
142                 if (!mExcludedEntityTypes.contains(entity)) {
143                     entities.add(entity);
144                 }
145             }
146             for (String entity : mIncludedEntityTypes) {
147                 if (!mExcludedEntityTypes.contains(entity) && !entities.contains(entity)) {
148                     entities.add(entity);
149                 }
150             }
151             return Collections.unmodifiableList(entities);
152         }
153 
154         @Override
describeContents()155         public int describeContents() {
156             return 0;
157         }
158 
159         @Override
writeToParcel(Parcel dest, int flags)160         public void writeToParcel(Parcel dest, int flags) {
161             dest.writeInt(mEntityPreset);
162             dest.writeStringList(new ArrayList<>(mExcludedEntityTypes));
163             dest.writeStringList(new ArrayList<>(mIncludedEntityTypes));
164         }
165 
166         public static final Parcelable.Creator<EntityConfig> CREATOR =
167                 new Parcelable.Creator<EntityConfig>() {
168                     @Override
169                     public EntityConfig createFromParcel(Parcel in) {
170                         return new EntityConfig(in);
171                     }
172 
173                     @Override
174                     public EntityConfig[] newArray(int size) {
175                         return new EntityConfig[size];
176                     }
177                 };
178 
EntityConfig(Parcel in)179         private EntityConfig(Parcel in) {
180             mEntityPreset = in.readInt();
181             mExcludedEntityTypes = new ArraySet<>(in.createStringArrayList());
182             mIncludedEntityTypes = new ArraySet<>(in.createStringArrayList());
183         }
184     }
185 }
186