Merge "Cleanup TextClassifier APIs"
This commit is contained in:
committed by
Android (Google) Code Review
commit
66f91878a0
@@ -53016,15 +53016,15 @@ package android.view.inspector {
|
||||
|
||||
package android.view.textclassifier {
|
||||
|
||||
public final class ConversationActions implements android.os.Parcelable {
|
||||
ctor public ConversationActions(java.util.List<android.view.textclassifier.ConversationActions.ConversationAction>, java.lang.String);
|
||||
public final class ConversationAction implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public java.util.List<android.view.textclassifier.ConversationActions.ConversationAction> getConversationActions();
|
||||
method public java.lang.String getId();
|
||||
method public android.app.RemoteAction getAction();
|
||||
method public float getConfidenceScore();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public java.lang.CharSequence getTextReply();
|
||||
method public java.lang.String getType();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.view.textclassifier.ConversationActions> CREATOR;
|
||||
field public static final java.lang.String HINT_FOR_IN_APP = "in_app";
|
||||
field public static final java.lang.String HINT_FOR_NOTIFICATION = "notification";
|
||||
field public static final android.os.Parcelable.Creator<android.view.textclassifier.ConversationAction> CREATOR;
|
||||
field public static final java.lang.String TYPE_CALL_PHONE = "call_phone";
|
||||
field public static final java.lang.String TYPE_CREATE_REMINDER = "create_reminder";
|
||||
field public static final java.lang.String TYPE_OPEN_URL = "open_url";
|
||||
@@ -53037,24 +53037,22 @@ package android.view.textclassifier {
|
||||
field public static final java.lang.String TYPE_VIEW_MAP = "view_map";
|
||||
}
|
||||
|
||||
public static final class ConversationActions.ConversationAction implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public android.app.RemoteAction getAction();
|
||||
method public float getConfidenceScore();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public java.lang.CharSequence getTextReply();
|
||||
method public java.lang.String getType();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.view.textclassifier.ConversationActions.ConversationAction> CREATOR;
|
||||
public static final class ConversationAction.Builder {
|
||||
ctor public ConversationAction.Builder(java.lang.String);
|
||||
method public android.view.textclassifier.ConversationAction build();
|
||||
method public android.view.textclassifier.ConversationAction.Builder setAction(android.app.RemoteAction);
|
||||
method public android.view.textclassifier.ConversationAction.Builder setConfidenceScore(float);
|
||||
method public android.view.textclassifier.ConversationAction.Builder setExtras(android.os.Bundle);
|
||||
method public android.view.textclassifier.ConversationAction.Builder setTextReply(java.lang.CharSequence);
|
||||
}
|
||||
|
||||
public static final class ConversationActions.ConversationAction.Builder {
|
||||
ctor public ConversationActions.ConversationAction.Builder(java.lang.String);
|
||||
method public android.view.textclassifier.ConversationActions.ConversationAction build();
|
||||
method public android.view.textclassifier.ConversationActions.ConversationAction.Builder setAction(android.app.RemoteAction);
|
||||
method public android.view.textclassifier.ConversationActions.ConversationAction.Builder setConfidenceScore(float);
|
||||
method public android.view.textclassifier.ConversationActions.ConversationAction.Builder setExtras(android.os.Bundle);
|
||||
method public android.view.textclassifier.ConversationActions.ConversationAction.Builder setTextReply(java.lang.CharSequence);
|
||||
public final class ConversationActions implements android.os.Parcelable {
|
||||
ctor public ConversationActions(java.util.List<android.view.textclassifier.ConversationAction>, java.lang.String);
|
||||
method public int describeContents();
|
||||
method public java.util.List<android.view.textclassifier.ConversationAction> getConversationActions();
|
||||
method public java.lang.String getId();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.view.textclassifier.ConversationActions> CREATOR;
|
||||
}
|
||||
|
||||
public static final class ConversationActions.Message implements android.os.Parcelable {
|
||||
@@ -53084,9 +53082,11 @@ package android.view.textclassifier {
|
||||
method public java.lang.String getConversationId();
|
||||
method public java.util.List<java.lang.String> getHints();
|
||||
method public int getMaxSuggestions();
|
||||
method public android.view.textclassifier.ConversationActions.TypeConfig getTypeConfig();
|
||||
method public android.view.textclassifier.TextClassifier.EntityConfig getTypeConfig();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.view.textclassifier.ConversationActions.Request> CREATOR;
|
||||
field public static final java.lang.String HINT_FOR_IN_APP = "in_app";
|
||||
field public static final java.lang.String HINT_FOR_NOTIFICATION = "notification";
|
||||
}
|
||||
|
||||
public static final class ConversationActions.Request.Builder {
|
||||
@@ -53095,23 +53095,7 @@ package android.view.textclassifier {
|
||||
method public android.view.textclassifier.ConversationActions.Request.Builder setConversationId(java.lang.String);
|
||||
method public android.view.textclassifier.ConversationActions.Request.Builder setHints(java.util.List<java.lang.String>);
|
||||
method public android.view.textclassifier.ConversationActions.Request.Builder setMaxSuggestions(int);
|
||||
method public android.view.textclassifier.ConversationActions.Request.Builder setTypeConfig(android.view.textclassifier.ConversationActions.TypeConfig);
|
||||
}
|
||||
|
||||
public static final class ConversationActions.TypeConfig implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public java.util.Collection<java.lang.String> resolveTypes(java.util.Collection<java.lang.String>);
|
||||
method public boolean shouldIncludeTypesFromTextClassifier();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.view.textclassifier.ConversationActions.TypeConfig> CREATOR;
|
||||
}
|
||||
|
||||
public static final class ConversationActions.TypeConfig.Builder {
|
||||
ctor public ConversationActions.TypeConfig.Builder();
|
||||
method public android.view.textclassifier.ConversationActions.TypeConfig build();
|
||||
method public android.view.textclassifier.ConversationActions.TypeConfig.Builder includeTypesFromTextClassifier(boolean);
|
||||
method public android.view.textclassifier.ConversationActions.TypeConfig.Builder setExcludedTypes(java.util.Collection<java.lang.String>);
|
||||
method public android.view.textclassifier.ConversationActions.TypeConfig.Builder setIncludedTypes(java.util.Collection<java.lang.String>);
|
||||
method public android.view.textclassifier.ConversationActions.Request.Builder setTypeConfig(android.view.textclassifier.TextClassifier.EntityConfig);
|
||||
}
|
||||
|
||||
public final class SelectionEvent implements android.os.Parcelable {
|
||||
@@ -53285,16 +53269,26 @@ package android.view.textclassifier {
|
||||
}
|
||||
|
||||
public static final class TextClassifier.EntityConfig implements android.os.Parcelable {
|
||||
method public static android.view.textclassifier.TextClassifier.EntityConfig create(java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>);
|
||||
method public static android.view.textclassifier.TextClassifier.EntityConfig createWithExplicitEntityList(java.util.Collection<java.lang.String>);
|
||||
method public static android.view.textclassifier.TextClassifier.EntityConfig createWithHints(java.util.Collection<java.lang.String>);
|
||||
method public static deprecated android.view.textclassifier.TextClassifier.EntityConfig create(java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>);
|
||||
method public static deprecated android.view.textclassifier.TextClassifier.EntityConfig createWithExplicitEntityList(java.util.Collection<java.lang.String>);
|
||||
method public static deprecated android.view.textclassifier.TextClassifier.EntityConfig createWithHints(java.util.Collection<java.lang.String>);
|
||||
method public int describeContents();
|
||||
method public java.util.Collection<java.lang.String> getHints();
|
||||
method public java.util.Collection<java.lang.String> resolveEntityListModifications(java.util.Collection<java.lang.String>);
|
||||
method public boolean shouldIncludeTypesFromTextClassifier();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.view.textclassifier.TextClassifier.EntityConfig> CREATOR;
|
||||
}
|
||||
|
||||
public static final class TextClassifier.EntityConfig.Builder {
|
||||
ctor public TextClassifier.EntityConfig.Builder();
|
||||
method public android.view.textclassifier.TextClassifier.EntityConfig build();
|
||||
method public android.view.textclassifier.TextClassifier.EntityConfig.Builder includeTypesFromTextClassifier(boolean);
|
||||
method public android.view.textclassifier.TextClassifier.EntityConfig.Builder setExcludedTypes(java.util.Collection<java.lang.String>);
|
||||
method public android.view.textclassifier.TextClassifier.EntityConfig.Builder setHints(java.util.Collection<java.lang.String>);
|
||||
method public android.view.textclassifier.TextClassifier.EntityConfig.Builder setIncludedTypes(java.util.Collection<java.lang.String>);
|
||||
}
|
||||
|
||||
public final class TextClassifierEvent implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int[] getActionIndices();
|
||||
|
||||
266
core/java/android/view/textclassifier/ConversationAction.java
Normal file
266
core/java/android/view/textclassifier/ConversationAction.java
Normal file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.view.textclassifier;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringDef;
|
||||
import android.app.RemoteAction;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
/** Represents the action suggested by a {@link TextClassifier} on a given conversation. */
|
||||
public final class ConversationAction implements Parcelable {
|
||||
|
||||
/** @hide */
|
||||
@Retention(SOURCE)
|
||||
@StringDef(
|
||||
value = {
|
||||
TYPE_VIEW_CALENDAR,
|
||||
TYPE_VIEW_MAP,
|
||||
TYPE_TRACK_FLIGHT,
|
||||
TYPE_OPEN_URL,
|
||||
TYPE_SEND_SMS,
|
||||
TYPE_CALL_PHONE,
|
||||
TYPE_SEND_EMAIL,
|
||||
TYPE_TEXT_REPLY,
|
||||
TYPE_CREATE_REMINDER,
|
||||
TYPE_SHARE_LOCATION
|
||||
},
|
||||
prefix = "TYPE_")
|
||||
public @interface ActionType {}
|
||||
|
||||
/**
|
||||
* Indicates an action to view a calendar at a specified time.
|
||||
*/
|
||||
public static final String TYPE_VIEW_CALENDAR = "view_calendar";
|
||||
/**
|
||||
* Indicates an action to view the map at a specified location.
|
||||
*/
|
||||
public static final String TYPE_VIEW_MAP = "view_map";
|
||||
/**
|
||||
* Indicates an action to track a flight.
|
||||
*/
|
||||
public static final String TYPE_TRACK_FLIGHT = "track_flight";
|
||||
/**
|
||||
* Indicates an action to open an URL.
|
||||
*/
|
||||
public static final String TYPE_OPEN_URL = "open_url";
|
||||
/**
|
||||
* Indicates an action to send a SMS.
|
||||
*/
|
||||
public static final String TYPE_SEND_SMS = "send_sms";
|
||||
/**
|
||||
* Indicates an action to call a phone number.
|
||||
*/
|
||||
public static final String TYPE_CALL_PHONE = "call_phone";
|
||||
/**
|
||||
* Indicates an action to send an email.
|
||||
*/
|
||||
public static final String TYPE_SEND_EMAIL = "send_email";
|
||||
/**
|
||||
* Indicates an action to reply with a text message.
|
||||
*/
|
||||
public static final String TYPE_TEXT_REPLY = "text_reply";
|
||||
/**
|
||||
* Indicates an action to create a reminder.
|
||||
*/
|
||||
public static final String TYPE_CREATE_REMINDER = "create_reminder";
|
||||
/**
|
||||
* Indicates an action to reply with a location.
|
||||
*/
|
||||
public static final String TYPE_SHARE_LOCATION = "share_location";
|
||||
|
||||
public static final Creator<ConversationAction> CREATOR =
|
||||
new Creator<ConversationAction>() {
|
||||
@Override
|
||||
public ConversationAction createFromParcel(Parcel in) {
|
||||
return new ConversationAction(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationAction[] newArray(int size) {
|
||||
return new ConversationAction[size];
|
||||
}
|
||||
};
|
||||
|
||||
@NonNull
|
||||
@ActionType
|
||||
private final String mType;
|
||||
@NonNull
|
||||
private final CharSequence mTextReply;
|
||||
@Nullable
|
||||
private final RemoteAction mAction;
|
||||
|
||||
@FloatRange(from = 0, to = 1)
|
||||
private final float mScore;
|
||||
|
||||
@NonNull
|
||||
private final Bundle mExtras;
|
||||
|
||||
private ConversationAction(
|
||||
@NonNull String type,
|
||||
@Nullable RemoteAction action,
|
||||
@Nullable CharSequence textReply,
|
||||
float score,
|
||||
@NonNull Bundle extras) {
|
||||
mType = Preconditions.checkNotNull(type);
|
||||
mAction = action;
|
||||
mTextReply = textReply;
|
||||
mScore = score;
|
||||
mExtras = Preconditions.checkNotNull(extras);
|
||||
}
|
||||
|
||||
private ConversationAction(Parcel in) {
|
||||
mType = in.readString();
|
||||
mAction = in.readParcelable(null);
|
||||
mTextReply = in.readCharSequence();
|
||||
mScore = in.readFloat();
|
||||
mExtras = in.readBundle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeString(mType);
|
||||
parcel.writeParcelable(mAction, flags);
|
||||
parcel.writeCharSequence(mTextReply);
|
||||
parcel.writeFloat(mScore);
|
||||
parcel.writeBundle(mExtras);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns the type of this action, for example, {@link #TYPE_VIEW_CALENDAR}. */
|
||||
@NonNull
|
||||
@ActionType
|
||||
public String getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a RemoteAction object, which contains the icon, label and a PendingIntent, for
|
||||
* the specified action type.
|
||||
*/
|
||||
@Nullable
|
||||
public RemoteAction getAction() {
|
||||
return mAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the confidence score for the specified action. The value ranges from 0 (low
|
||||
* confidence) to 1 (high confidence).
|
||||
*/
|
||||
@FloatRange(from = 0, to = 1)
|
||||
public float getConfidenceScore() {
|
||||
return mScore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text reply that could be sent as a reply to the given conversation.
|
||||
* <p>
|
||||
* This is only available when the type of the action is {@link #TYPE_TEXT_REPLY}.
|
||||
*/
|
||||
@Nullable
|
||||
public CharSequence getTextReply() {
|
||||
return mTextReply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extended data related to this conversation action.
|
||||
*
|
||||
* <p><b>NOTE: </b>Each call to this method returns a new bundle copy so clients should
|
||||
* prefer to hold a reference to the returned bundle rather than frequently calling this
|
||||
* method.
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getExtras() {
|
||||
return mExtras.deepCopy();
|
||||
}
|
||||
|
||||
/** Builder class to construct {@link ConversationAction}. */
|
||||
public static final class Builder {
|
||||
@Nullable
|
||||
@ActionType
|
||||
private String mType;
|
||||
@Nullable
|
||||
private RemoteAction mAction;
|
||||
@Nullable
|
||||
private CharSequence mTextReply;
|
||||
private float mScore;
|
||||
@Nullable
|
||||
private Bundle mExtras;
|
||||
|
||||
public Builder(@NonNull @ActionType String actionType) {
|
||||
mType = Preconditions.checkNotNull(actionType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an action that may be performed on the given conversation.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setAction(@Nullable RemoteAction action) {
|
||||
mAction = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a text reply that may be performed on the given conversation.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setTextReply(@Nullable CharSequence textReply) {
|
||||
mTextReply = textReply;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the confident score. */
|
||||
@NonNull
|
||||
public Builder setConfidenceScore(@FloatRange(from = 0, to = 1) float score) {
|
||||
mScore = score;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the extended data for the conversation action object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setExtras(@Nullable Bundle extras) {
|
||||
mExtras = extras;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the {@link ConversationAction} object. */
|
||||
@NonNull
|
||||
public ConversationAction build() {
|
||||
return new ConversationAction(
|
||||
mType,
|
||||
mAction,
|
||||
mTextReply,
|
||||
mScore,
|
||||
mExtras == null ? Bundle.EMPTY : mExtras.deepCopy());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,18 +17,15 @@ package android.view.textclassifier;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringDef;
|
||||
import android.app.Person;
|
||||
import android.app.RemoteAction;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.SpannedString;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.Preconditions;
|
||||
@@ -37,10 +34,8 @@ import java.lang.annotation.Retention;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents a list of actions suggested by a {@link TextClassifier} on a given conversation.
|
||||
@@ -62,83 +57,6 @@ public final class ConversationActions implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
/** @hide */
|
||||
@Retention(SOURCE)
|
||||
@StringDef(
|
||||
value = {
|
||||
TYPE_VIEW_CALENDAR,
|
||||
TYPE_VIEW_MAP,
|
||||
TYPE_TRACK_FLIGHT,
|
||||
TYPE_OPEN_URL,
|
||||
TYPE_SEND_SMS,
|
||||
TYPE_CALL_PHONE,
|
||||
TYPE_SEND_EMAIL,
|
||||
TYPE_TEXT_REPLY,
|
||||
TYPE_CREATE_REMINDER,
|
||||
TYPE_SHARE_LOCATION
|
||||
},
|
||||
prefix = "TYPE_")
|
||||
public @interface ActionType {}
|
||||
|
||||
/**
|
||||
* Indicates an action to view a calendar at a specified time.
|
||||
*/
|
||||
public static final String TYPE_VIEW_CALENDAR = "view_calendar";
|
||||
/**
|
||||
* Indicates an action to view the map at a specified location.
|
||||
*/
|
||||
public static final String TYPE_VIEW_MAP = "view_map";
|
||||
/**
|
||||
* Indicates an action to track a flight.
|
||||
*/
|
||||
public static final String TYPE_TRACK_FLIGHT = "track_flight";
|
||||
/**
|
||||
* Indicates an action to open an URL.
|
||||
*/
|
||||
public static final String TYPE_OPEN_URL = "open_url";
|
||||
/**
|
||||
* Indicates an action to send a SMS.
|
||||
*/
|
||||
public static final String TYPE_SEND_SMS = "send_sms";
|
||||
/**
|
||||
* Indicates an action to call a phone number.
|
||||
*/
|
||||
public static final String TYPE_CALL_PHONE = "call_phone";
|
||||
/**
|
||||
* Indicates an action to send an email.
|
||||
*/
|
||||
public static final String TYPE_SEND_EMAIL = "send_email";
|
||||
/**
|
||||
* Indicates an action to reply with a text message.
|
||||
*/
|
||||
public static final String TYPE_TEXT_REPLY = "text_reply";
|
||||
/**
|
||||
* Indicates an action to create a reminder.
|
||||
*/
|
||||
public static final String TYPE_CREATE_REMINDER = "create_reminder";
|
||||
/**
|
||||
* Indicates an action to reply with a location.
|
||||
*/
|
||||
public static final String TYPE_SHARE_LOCATION = "share_location";
|
||||
|
||||
/** @hide */
|
||||
@Retention(SOURCE)
|
||||
@StringDef(
|
||||
value = {
|
||||
HINT_FOR_NOTIFICATION,
|
||||
HINT_FOR_IN_APP,
|
||||
},
|
||||
prefix = "HINT_")
|
||||
public @interface Hint {}
|
||||
/**
|
||||
* To indicate the generated actions will be used within the app.
|
||||
*/
|
||||
public static final String HINT_FOR_IN_APP = "in_app";
|
||||
/**
|
||||
* To indicate the generated actions will be used for notification.
|
||||
*/
|
||||
public static final String HINT_FOR_NOTIFICATION = "notification";
|
||||
|
||||
private final List<ConversationAction> mConversationActions;
|
||||
private final String mId;
|
||||
|
||||
@@ -184,182 +102,6 @@ public final class ConversationActions implements Parcelable {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/** Represents the action suggested by a {@link TextClassifier} on a given conversation. */
|
||||
public static final class ConversationAction implements Parcelable {
|
||||
|
||||
public static final Creator<ConversationAction> CREATOR =
|
||||
new Creator<ConversationAction>() {
|
||||
@Override
|
||||
public ConversationAction createFromParcel(Parcel in) {
|
||||
return new ConversationAction(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationAction[] newArray(int size) {
|
||||
return new ConversationAction[size];
|
||||
}
|
||||
};
|
||||
|
||||
@NonNull
|
||||
@ActionType
|
||||
private final String mType;
|
||||
@NonNull
|
||||
private final CharSequence mTextReply;
|
||||
@Nullable
|
||||
private final RemoteAction mAction;
|
||||
|
||||
@FloatRange(from = 0, to = 1)
|
||||
private final float mScore;
|
||||
|
||||
@NonNull
|
||||
private final Bundle mExtras;
|
||||
|
||||
private ConversationAction(
|
||||
@NonNull String type,
|
||||
@Nullable RemoteAction action,
|
||||
@Nullable CharSequence textReply,
|
||||
float score,
|
||||
@NonNull Bundle extras) {
|
||||
mType = Preconditions.checkNotNull(type);
|
||||
mAction = action;
|
||||
mTextReply = textReply;
|
||||
mScore = score;
|
||||
mExtras = Preconditions.checkNotNull(extras);
|
||||
}
|
||||
|
||||
private ConversationAction(Parcel in) {
|
||||
mType = in.readString();
|
||||
mAction = in.readParcelable(null);
|
||||
mTextReply = in.readCharSequence();
|
||||
mScore = in.readFloat();
|
||||
mExtras = in.readBundle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeString(mType);
|
||||
parcel.writeParcelable(mAction, flags);
|
||||
parcel.writeCharSequence(mTextReply);
|
||||
parcel.writeFloat(mScore);
|
||||
parcel.writeBundle(mExtras);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ActionType
|
||||
/** Returns the type of this action, for example, {@link #TYPE_VIEW_CALENDAR}. */
|
||||
public String getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
/**
|
||||
* Returns a RemoteAction object, which contains the icon, label and a PendingIntent, for
|
||||
* the specified action type.
|
||||
*/
|
||||
public RemoteAction getAction() {
|
||||
return mAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the confidence score for the specified action. The value ranges from 0 (low
|
||||
* confidence) to 1 (high confidence).
|
||||
*/
|
||||
@FloatRange(from = 0, to = 1)
|
||||
public float getConfidenceScore() {
|
||||
return mScore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text reply that could be sent as a reply to the given conversation.
|
||||
* <p>
|
||||
* This is only available when the type of the action is {@link #TYPE_TEXT_REPLY}.
|
||||
*/
|
||||
@Nullable
|
||||
public CharSequence getTextReply() {
|
||||
return mTextReply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extended data related to this conversation action.
|
||||
*
|
||||
* <p><b>NOTE: </b>Each call to this method returns a new bundle copy so clients should
|
||||
* prefer to hold a reference to the returned bundle rather than frequently calling this
|
||||
* method.
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getExtras() {
|
||||
return mExtras.deepCopy();
|
||||
}
|
||||
|
||||
/** Builder class to construct {@link ConversationAction}. */
|
||||
public static final class Builder {
|
||||
@Nullable
|
||||
@ActionType
|
||||
private String mType;
|
||||
@Nullable
|
||||
private RemoteAction mAction;
|
||||
@Nullable
|
||||
private CharSequence mTextReply;
|
||||
private float mScore;
|
||||
@Nullable
|
||||
private Bundle mExtras;
|
||||
|
||||
public Builder(@NonNull @ActionType String actionType) {
|
||||
mType = Preconditions.checkNotNull(actionType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an action that may be performed on the given conversation.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setAction(@Nullable RemoteAction action) {
|
||||
mAction = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a text reply that may be performed on the given conversation.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setTextReply(@Nullable CharSequence textReply) {
|
||||
mTextReply = textReply;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the confident score. */
|
||||
@NonNull
|
||||
public Builder setConfidenceScore(@FloatRange(from = 0, to = 1) float score) {
|
||||
mScore = score;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the extended data for the conversation action object.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setExtras(@Nullable Bundle extras) {
|
||||
mExtras = extras;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the {@link ConversationAction} object. */
|
||||
@NonNull
|
||||
public ConversationAction build() {
|
||||
return new ConversationAction(
|
||||
mType,
|
||||
mAction,
|
||||
mTextReply,
|
||||
mScore,
|
||||
mExtras == null ? Bundle.EMPTY : mExtras.deepCopy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents a message in the conversation. */
|
||||
public static final class Message implements Parcelable {
|
||||
/**
|
||||
@@ -538,156 +280,36 @@ public final class ConversationActions implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/** Configuration object for specifying what action types to identify. */
|
||||
public static final class TypeConfig implements Parcelable {
|
||||
@NonNull
|
||||
@ActionType
|
||||
private final Set<String> mExcludedTypes;
|
||||
@NonNull
|
||||
@ActionType
|
||||
private final Set<String> mIncludedTypes;
|
||||
private final boolean mIncludeTypesFromTextClassifier;
|
||||
|
||||
private TypeConfig(
|
||||
@NonNull Set<String> includedTypes,
|
||||
@NonNull Set<String> excludedTypes,
|
||||
boolean includeTypesFromTextClassifier) {
|
||||
mIncludedTypes = Preconditions.checkNotNull(includedTypes);
|
||||
mExcludedTypes = Preconditions.checkNotNull(excludedTypes);
|
||||
mIncludeTypesFromTextClassifier = includeTypesFromTextClassifier;
|
||||
}
|
||||
|
||||
private TypeConfig(Parcel in) {
|
||||
mIncludedTypes = new ArraySet<>(in.createStringArrayList());
|
||||
mExcludedTypes = new ArraySet<>(in.createStringArrayList());
|
||||
mIncludeTypesFromTextClassifier = in.readByte() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeStringList(new ArrayList<>(mIncludedTypes));
|
||||
parcel.writeStringList(new ArrayList<>(mExcludedTypes));
|
||||
parcel.writeByte((byte) (mIncludeTypesFromTextClassifier ? 1 : 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<TypeConfig> CREATOR =
|
||||
new Creator<TypeConfig>() {
|
||||
@Override
|
||||
public TypeConfig createFromParcel(Parcel in) {
|
||||
return new TypeConfig(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConfig[] newArray(int size) {
|
||||
return new TypeConfig[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a final list of types that the text classifier should look for.
|
||||
*
|
||||
* <p>NOTE: This method is intended for use by a text classifier.
|
||||
*
|
||||
* @param defaultTypes types the text classifier thinks should be included before factoring
|
||||
* in the included/excluded types given by the client.
|
||||
*/
|
||||
@NonNull
|
||||
public Collection<String> resolveTypes(@Nullable Collection<String> defaultTypes) {
|
||||
Set<String> types = new ArraySet<>();
|
||||
if (mIncludeTypesFromTextClassifier && defaultTypes != null) {
|
||||
types.addAll(defaultTypes);
|
||||
}
|
||||
types.addAll(mIncludedTypes);
|
||||
types.removeAll(mExcludedTypes);
|
||||
return Collections.unmodifiableCollection(types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the client allows the text classifier to include its own list of default
|
||||
* types. If this function returns {@code true}, the text classifier can consider specifying
|
||||
* a default list of entity types in {@link #resolveTypes(Collection)}.
|
||||
*
|
||||
* <p>NOTE: This method is intended for use by a text classifier.
|
||||
*
|
||||
* @see #resolveTypes(Collection)
|
||||
*/
|
||||
public boolean shouldIncludeTypesFromTextClassifier() {
|
||||
return mIncludeTypesFromTextClassifier;
|
||||
}
|
||||
|
||||
/** Builder class to construct the {@link TypeConfig} object. */
|
||||
public static final class Builder {
|
||||
@Nullable
|
||||
private Collection<String> mExcludedTypes;
|
||||
@Nullable
|
||||
private Collection<String> mIncludedTypes;
|
||||
private boolean mIncludeTypesFromTextClassifier = true;
|
||||
|
||||
/**
|
||||
* Sets a collection of types that are explicitly included, for example, {@link
|
||||
* #TYPE_VIEW_CALENDAR}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setIncludedTypes(
|
||||
@Nullable @ActionType Collection<String> includedTypes) {
|
||||
mIncludedTypes = includedTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a collection of types that are explicitly excluded, for example, {@link
|
||||
* #TYPE_VIEW_CALENDAR}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setExcludedTypes(
|
||||
@Nullable @ActionType Collection<String> excludedTypes) {
|
||||
mExcludedTypes = excludedTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether or not to include the types suggested by the text classifier. By
|
||||
* default, it is included.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder includeTypesFromTextClassifier(boolean includeTypesFromTextClassifier) {
|
||||
mIncludeTypesFromTextClassifier = includeTypesFromTextClassifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines all of the options that have been set and returns a new {@link TypeConfig}
|
||||
* object.
|
||||
*/
|
||||
@NonNull
|
||||
public TypeConfig build() {
|
||||
return new TypeConfig(
|
||||
mIncludedTypes == null
|
||||
? Collections.emptySet()
|
||||
: new ArraySet<>(mIncludedTypes),
|
||||
mExcludedTypes == null
|
||||
? Collections.emptySet()
|
||||
: new ArraySet<>(mExcludedTypes),
|
||||
mIncludeTypesFromTextClassifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A request object for generating conversation action suggestions.
|
||||
*
|
||||
* @see TextClassifier#suggestConversationActions(Request)
|
||||
*/
|
||||
public static final class Request implements Parcelable {
|
||||
|
||||
/** @hide */
|
||||
@Retention(SOURCE)
|
||||
@StringDef(
|
||||
value = {
|
||||
HINT_FOR_NOTIFICATION,
|
||||
HINT_FOR_IN_APP,
|
||||
},
|
||||
prefix = "HINT_")
|
||||
public @interface Hint {}
|
||||
|
||||
/**
|
||||
* To indicate the generated actions will be used within the app.
|
||||
*/
|
||||
public static final String HINT_FOR_IN_APP = "in_app";
|
||||
/**
|
||||
* To indicate the generated actions will be used for notification.
|
||||
*/
|
||||
public static final String HINT_FOR_NOTIFICATION = "notification";
|
||||
|
||||
@NonNull
|
||||
private final List<Message> mConversation;
|
||||
@NonNull
|
||||
private final TypeConfig mTypeConfig;
|
||||
private final TextClassifier.EntityConfig mTypeConfig;
|
||||
private final int mMaxSuggestions;
|
||||
@NonNull
|
||||
@Hint
|
||||
@@ -699,7 +321,7 @@ public final class ConversationActions implements Parcelable {
|
||||
|
||||
private Request(
|
||||
@NonNull List<Message> conversation,
|
||||
@NonNull TypeConfig typeConfig,
|
||||
@NonNull TextClassifier.EntityConfig typeConfig,
|
||||
int maxSuggestions,
|
||||
String conversationId,
|
||||
@Nullable @Hint List<String> hints) {
|
||||
@@ -713,7 +335,7 @@ public final class ConversationActions implements Parcelable {
|
||||
private static Request readFromParcel(Parcel in) {
|
||||
List<Message> conversation = new ArrayList<>();
|
||||
in.readParcelableList(conversation, null);
|
||||
TypeConfig typeConfig = in.readParcelable(null);
|
||||
TextClassifier.EntityConfig typeConfig = in.readParcelable(null);
|
||||
int maxSuggestions = in.readInt();
|
||||
String conversationId = in.readString();
|
||||
List<String> hints = new ArrayList<>();
|
||||
@@ -760,7 +382,7 @@ public final class ConversationActions implements Parcelable {
|
||||
|
||||
/** Returns the type config. */
|
||||
@NonNull
|
||||
public TypeConfig getTypeConfig() {
|
||||
public TextClassifier.EntityConfig getTypeConfig() {
|
||||
return mTypeConfig;
|
||||
}
|
||||
|
||||
@@ -820,7 +442,7 @@ public final class ConversationActions implements Parcelable {
|
||||
@NonNull
|
||||
private List<Message> mConversation;
|
||||
@Nullable
|
||||
private TypeConfig mTypeConfig;
|
||||
private TextClassifier.EntityConfig mTypeConfig;
|
||||
private int mMaxSuggestions;
|
||||
@Nullable
|
||||
private String mConversationId;
|
||||
@@ -849,7 +471,7 @@ public final class ConversationActions implements Parcelable {
|
||||
|
||||
/** Sets the type config. */
|
||||
@NonNull
|
||||
public Builder setTypeConfig(@Nullable TypeConfig typeConfig) {
|
||||
public Builder setTypeConfig(@Nullable TextClassifier.EntityConfig typeConfig) {
|
||||
mTypeConfig = typeConfig;
|
||||
return this;
|
||||
}
|
||||
@@ -879,7 +501,9 @@ public final class ConversationActions implements Parcelable {
|
||||
public Request build() {
|
||||
return new Request(
|
||||
Collections.unmodifiableList(mConversation),
|
||||
mTypeConfig == null ? new TypeConfig.Builder().build() : mTypeConfig,
|
||||
mTypeConfig == null
|
||||
? new TextClassifier.EntityConfig.Builder().build()
|
||||
: mTypeConfig,
|
||||
mMaxSuggestions,
|
||||
mConversationId,
|
||||
mHints == null
|
||||
|
||||
@@ -117,15 +117,15 @@ public final class TextClassificationConstants {
|
||||
.add(TextClassifier.TYPE_FLIGHT_NUMBER).toString();
|
||||
private static final String CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES =
|
||||
new StringJoiner(ENTITY_LIST_DELIMITER)
|
||||
.add(ConversationActions.TYPE_TEXT_REPLY)
|
||||
.add(ConversationActions.TYPE_CREATE_REMINDER)
|
||||
.add(ConversationActions.TYPE_CALL_PHONE)
|
||||
.add(ConversationActions.TYPE_OPEN_URL)
|
||||
.add(ConversationActions.TYPE_SEND_EMAIL)
|
||||
.add(ConversationActions.TYPE_SEND_SMS)
|
||||
.add(ConversationActions.TYPE_TRACK_FLIGHT)
|
||||
.add(ConversationActions.TYPE_VIEW_CALENDAR)
|
||||
.add(ConversationActions.TYPE_VIEW_MAP)
|
||||
.add(ConversationAction.TYPE_TEXT_REPLY)
|
||||
.add(ConversationAction.TYPE_CREATE_REMINDER)
|
||||
.add(ConversationAction.TYPE_CALL_PHONE)
|
||||
.add(ConversationAction.TYPE_OPEN_URL)
|
||||
.add(ConversationAction.TYPE_SEND_EMAIL)
|
||||
.add(ConversationAction.TYPE_SEND_SMS)
|
||||
.add(ConversationAction.TYPE_TRACK_FLIGHT)
|
||||
.add(ConversationAction.TYPE_VIEW_CALENDAR)
|
||||
.add(ConversationAction.TYPE_VIEW_MAP)
|
||||
.toString();
|
||||
|
||||
private final boolean mSystemTextClassifierEnabled;
|
||||
|
||||
@@ -32,7 +32,6 @@ import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.text.util.Linkify.LinkifyMask;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.internal.util.Preconditions;
|
||||
@@ -43,6 +42,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -324,7 +324,7 @@ public interface TextClassifier {
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the language of the specified text.
|
||||
* Detects the language of the text in the given request.
|
||||
*
|
||||
* <p><strong>NOTE: </strong>Call on a worker thread.
|
||||
*
|
||||
@@ -403,42 +403,59 @@ public interface TextClassifier {
|
||||
default void dump(@NonNull IndentingPrintWriter printWriter) {}
|
||||
|
||||
/**
|
||||
* Configuration object for specifying what entities to identify.
|
||||
* Configuration object for specifying what entity types to identify.
|
||||
*
|
||||
* Configs are initially based on a predefined preset, and can be modified from there.
|
||||
*/
|
||||
final class EntityConfig implements Parcelable {
|
||||
private final Collection<String> mHints;
|
||||
private final Collection<String> mExcludedEntityTypes;
|
||||
private final Collection<String> mIncludedEntityTypes;
|
||||
private final boolean mUseHints;
|
||||
private final List<String> mIncludedTypes;
|
||||
private final List<String> mExcludedTypes;
|
||||
private final List<String> mHints;
|
||||
private final boolean mIncludeTypesFromTextClassifier;
|
||||
|
||||
private EntityConfig(boolean useHints, Collection<String> hints,
|
||||
Collection<String> includedEntityTypes, Collection<String> excludedEntityTypes) {
|
||||
mHints = hints == null
|
||||
? Collections.EMPTY_LIST
|
||||
: Collections.unmodifiableCollection(new ArraySet<>(hints));
|
||||
mExcludedEntityTypes = excludedEntityTypes == null
|
||||
? Collections.EMPTY_LIST : new ArraySet<>(excludedEntityTypes);
|
||||
mIncludedEntityTypes = includedEntityTypes == null
|
||||
? Collections.EMPTY_LIST : new ArraySet<>(includedEntityTypes);
|
||||
mUseHints = useHints;
|
||||
private EntityConfig(
|
||||
List<String> includedEntityTypes,
|
||||
List<String> excludedEntityTypes,
|
||||
List<String> hints,
|
||||
boolean includeTypesFromTextClassifier) {
|
||||
mIncludedTypes = Preconditions.checkNotNull(includedEntityTypes);
|
||||
mExcludedTypes = Preconditions.checkNotNull(excludedEntityTypes);
|
||||
mHints = Preconditions.checkNotNull(hints);
|
||||
mIncludeTypesFromTextClassifier = includeTypesFromTextClassifier;
|
||||
}
|
||||
|
||||
private EntityConfig(Parcel in) {
|
||||
mIncludedTypes = new ArrayList<>();
|
||||
in.readStringList(mIncludedTypes);
|
||||
mExcludedTypes = new ArrayList<>();
|
||||
in.readStringList(mExcludedTypes);
|
||||
List<String> tmpHints = new ArrayList<>();
|
||||
in.readStringList(tmpHints);
|
||||
mHints = Collections.unmodifiableList(tmpHints);
|
||||
mIncludeTypesFromTextClassifier = in.readByte() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeStringList(mIncludedTypes);
|
||||
parcel.writeStringList(mExcludedTypes);
|
||||
parcel.writeStringList(mHints);
|
||||
parcel.writeByte((byte) (mIncludeTypesFromTextClassifier ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an EntityConfig.
|
||||
*
|
||||
* @param hints Hints for the TextClassifier to determine what types of entities to find.
|
||||
*
|
||||
* @deprecated Use {@link Builder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static EntityConfig createWithHints(@Nullable Collection<String> hints) {
|
||||
return new EntityConfig(/* useHints */ true, hints,
|
||||
/* includedEntityTypes */null, /* excludedEntityTypes */ null);
|
||||
}
|
||||
|
||||
// TODO: Remove once apps can build against the latest sdk.
|
||||
/** @hide */
|
||||
public static EntityConfig create(@Nullable Collection<String> hints) {
|
||||
return createWithHints(hints);
|
||||
return new EntityConfig.Builder()
|
||||
.includeTypesFromTextClassifier(true)
|
||||
.setHints(hints)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,12 +467,19 @@ public interface TextClassifier {
|
||||
*
|
||||
*
|
||||
* Note that if an entity has been excluded, the exclusion will take precedence.
|
||||
*
|
||||
* @deprecated Use {@link Builder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static EntityConfig create(@Nullable Collection<String> hints,
|
||||
@Nullable Collection<String> includedEntityTypes,
|
||||
@Nullable Collection<String> excludedEntityTypes) {
|
||||
return new EntityConfig(/* useHints */ true, hints,
|
||||
includedEntityTypes, excludedEntityTypes);
|
||||
return new EntityConfig.Builder()
|
||||
.setIncludedTypes(includedEntityTypes)
|
||||
.setExcludedTypes(excludedEntityTypes)
|
||||
.setHints(hints)
|
||||
.includeTypesFromTextClassifier(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,34 +487,33 @@ public interface TextClassifier {
|
||||
*
|
||||
* @param entityTypes Complete set of entities, e.g. {@link #TYPE_URL} to find.
|
||||
*
|
||||
* @deprecated Use {@link Builder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static EntityConfig createWithExplicitEntityList(
|
||||
@Nullable Collection<String> entityTypes) {
|
||||
return new EntityConfig(/* useHints */ false, /* hints */ null,
|
||||
/* includedEntityTypes */ entityTypes, /* excludedEntityTypes */ null);
|
||||
}
|
||||
|
||||
// TODO: Remove once apps can build against the latest sdk.
|
||||
/** @hide */
|
||||
public static EntityConfig createWithEntityList(@Nullable Collection<String> entityTypes) {
|
||||
return createWithExplicitEntityList(entityTypes);
|
||||
return new EntityConfig.Builder()
|
||||
.setIncludedTypes(entityTypes)
|
||||
.includeTypesFromTextClassifier(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the final set of entities to find.
|
||||
* Returns a final list of entity types to find.
|
||||
*
|
||||
* @param entities Entities we think should be found before factoring in includes/excludes
|
||||
* @param entityTypes Entity types we think should be found before factoring in
|
||||
* includes/excludes
|
||||
*
|
||||
* This method is intended for use by TextClassifier implementations.
|
||||
*/
|
||||
public Collection<String> resolveEntityListModifications(
|
||||
@NonNull Collection<String> entities) {
|
||||
final Set<String> finalSet = new HashSet();
|
||||
if (mUseHints) {
|
||||
finalSet.addAll(entities);
|
||||
@NonNull Collection<String> entityTypes) {
|
||||
final Set<String> finalSet = new HashSet<>();
|
||||
if (mIncludeTypesFromTextClassifier) {
|
||||
finalSet.addAll(entityTypes);
|
||||
}
|
||||
finalSet.addAll(mIncludedEntityTypes);
|
||||
finalSet.removeAll(mExcludedEntityTypes);
|
||||
finalSet.addAll(mIncludedTypes);
|
||||
finalSet.removeAll(mExcludedTypes);
|
||||
return finalSet;
|
||||
}
|
||||
|
||||
@@ -503,17 +526,22 @@ public interface TextClassifier {
|
||||
return mHints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
/**
|
||||
* Return whether the client allows the text classifier to include its own list of
|
||||
* default types. If this function returns {@code true}, a default list of types suggested
|
||||
* from a text classifier will be taking into account.
|
||||
*
|
||||
* <p>NOTE: This method is intended for use by a text classifier.
|
||||
*
|
||||
* @see #resolveEntityListModifications(Collection)
|
||||
*/
|
||||
public boolean shouldIncludeTypesFromTextClassifier() {
|
||||
return mIncludeTypesFromTextClassifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeStringList(new ArrayList<>(mHints));
|
||||
dest.writeStringList(new ArrayList<>(mExcludedEntityTypes));
|
||||
dest.writeStringList(new ArrayList<>(mIncludedEntityTypes));
|
||||
dest.writeInt(mUseHints ? 1 : 0);
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<EntityConfig> CREATOR =
|
||||
@@ -529,11 +557,75 @@ public interface TextClassifier {
|
||||
}
|
||||
};
|
||||
|
||||
private EntityConfig(Parcel in) {
|
||||
mHints = new ArraySet<>(in.createStringArrayList());
|
||||
mExcludedEntityTypes = new ArraySet<>(in.createStringArrayList());
|
||||
mIncludedEntityTypes = new ArraySet<>(in.createStringArrayList());
|
||||
mUseHints = in.readInt() == 1;
|
||||
|
||||
|
||||
/** Builder class to construct the {@link EntityConfig} object. */
|
||||
public static final class Builder {
|
||||
@Nullable
|
||||
private Collection<String> mIncludedTypes;
|
||||
@Nullable
|
||||
private Collection<String> mExcludedTypes;
|
||||
@Nullable
|
||||
private Collection<String> mHints;
|
||||
private boolean mIncludeTypesFromTextClassifier = true;
|
||||
|
||||
/**
|
||||
* Sets a collection of types that are explicitly included.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setIncludedTypes(@Nullable Collection<String> includedTypes) {
|
||||
mIncludedTypes = includedTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a collection of types that are explicitly excluded.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setExcludedTypes(@Nullable Collection<String> excludedTypes) {
|
||||
mExcludedTypes = excludedTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether or not to include the types suggested by the text classifier. By
|
||||
* default, it is included.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder includeTypesFromTextClassifier(boolean includeTypesFromTextClassifier) {
|
||||
mIncludeTypesFromTextClassifier = includeTypesFromTextClassifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the hints for the TextClassifier to determine what types of entities to find.
|
||||
* These hints will only be used if {@link #includeTypesFromTextClassifier} is
|
||||
* set to be true.
|
||||
*/
|
||||
public Builder setHints(Collection<String> hints) {
|
||||
mHints = hints;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines all of the options that have been set and returns a new {@link EntityConfig}
|
||||
* object.
|
||||
*/
|
||||
@NonNull
|
||||
public EntityConfig build() {
|
||||
return new EntityConfig(
|
||||
mIncludedTypes == null
|
||||
? Collections.emptyList()
|
||||
: new ArrayList<>(mIncludedTypes),
|
||||
mExcludedTypes == null
|
||||
? Collections.emptyList()
|
||||
: new ArrayList<>(mExcludedTypes),
|
||||
mHints == null
|
||||
? Collections.emptyList()
|
||||
: Collections.unmodifiableList(new ArrayList<>(mHints)),
|
||||
mIncludeTypesFromTextClassifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -393,7 +393,7 @@ public final class TextClassifierImpl implements TextClassifier {
|
||||
actionsImpl.suggestActions(nativeConversation, null);
|
||||
|
||||
Collection<String> expectedTypes = resolveActionTypesFromRequest(request);
|
||||
List<ConversationActions.ConversationAction> conversationActions = new ArrayList<>();
|
||||
List<ConversationAction> conversationActions = new ArrayList<>();
|
||||
int maxSuggestions = nativeSuggestions.length;
|
||||
if (request.getMaxSuggestions() > 0) {
|
||||
maxSuggestions = Math.min(request.getMaxSuggestions(), nativeSuggestions.length);
|
||||
@@ -405,7 +405,7 @@ public final class TextClassifierImpl implements TextClassifier {
|
||||
continue;
|
||||
}
|
||||
conversationActions.add(
|
||||
new ConversationActions.ConversationAction.Builder(actionType)
|
||||
new ConversationAction.Builder(actionType)
|
||||
.setTextReply(nativeSuggestion.getResponseText())
|
||||
.setConfidenceScore(nativeSuggestion.getScore())
|
||||
.build());
|
||||
@@ -445,10 +445,10 @@ public final class TextClassifierImpl implements TextClassifier {
|
||||
|
||||
private Collection<String> resolveActionTypesFromRequest(ConversationActions.Request request) {
|
||||
List<String> defaultActionTypes =
|
||||
request.getHints().contains(ConversationActions.HINT_FOR_NOTIFICATION)
|
||||
request.getHints().contains(ConversationActions.Request.HINT_FOR_NOTIFICATION)
|
||||
? mSettings.getNotificationConversationActionTypes()
|
||||
: mSettings.getInAppConversationActionTypes();
|
||||
return request.getTypeConfig().resolveTypes(defaultActionTypes);
|
||||
return request.getTypeConfig().resolveEntityListModifications(defaultActionTypes);
|
||||
}
|
||||
|
||||
private AnnotatorModel getAnnotatorImpl(LocaleList localeList)
|
||||
|
||||
@@ -377,10 +377,10 @@ public class TextClassifierTest {
|
||||
ConversationActions.Message.PERSON_USER_REMOTE)
|
||||
.setText("Where are you?")
|
||||
.build();
|
||||
ConversationActions.TypeConfig typeConfig =
|
||||
new ConversationActions.TypeConfig.Builder().includeTypesFromTextClassifier(false)
|
||||
TextClassifier.EntityConfig typeConfig =
|
||||
new TextClassifier.EntityConfig.Builder().includeTypesFromTextClassifier(false)
|
||||
.setIncludedTypes(
|
||||
Collections.singletonList(ConversationActions.TYPE_TEXT_REPLY))
|
||||
Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
|
||||
.build();
|
||||
ConversationActions.Request request =
|
||||
new ConversationActions.Request.Builder(Collections.singletonList(message))
|
||||
@@ -391,10 +391,10 @@ public class TextClassifierTest {
|
||||
ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
|
||||
assertTrue(conversationActions.getConversationActions().size() > 0);
|
||||
assertTrue(conversationActions.getConversationActions().size() == 1);
|
||||
for (ConversationActions.ConversationAction conversationAction :
|
||||
for (ConversationAction conversationAction :
|
||||
conversationActions.getConversationActions()) {
|
||||
assertThat(conversationAction,
|
||||
isConversationAction(ConversationActions.TYPE_TEXT_REPLY));
|
||||
isConversationAction(ConversationAction.TYPE_TEXT_REPLY));
|
||||
}
|
||||
}*/
|
||||
|
||||
@@ -406,10 +406,10 @@ public class TextClassifierTest {
|
||||
ConversationActions.Message.PERSON_USER_REMOTE)
|
||||
.setText("Where are you?")
|
||||
.build();
|
||||
ConversationActions.TypeConfig typeConfig =
|
||||
new ConversationActions.TypeConfig.Builder().includeTypesFromTextClassifier(false)
|
||||
TextClassifier.EntityConfig typeConfig =
|
||||
new TextClassifier.EntityConfig.Builder().includeTypesFromTextClassifier(false)
|
||||
.setIncludedTypes(
|
||||
Collections.singletonList(ConversationActions.TYPE_TEXT_REPLY))
|
||||
Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
|
||||
.build();
|
||||
ConversationActions.Request request =
|
||||
new ConversationActions.Request.Builder(Collections.singletonList(message))
|
||||
@@ -418,10 +418,10 @@ public class TextClassifierTest {
|
||||
|
||||
ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
|
||||
assertTrue(conversationActions.getConversationActions().size() > 1);
|
||||
for (ConversationActions.ConversationAction conversationAction :
|
||||
for (ConversationAction conversationAction :
|
||||
conversationActions.getConversationActions()) {
|
||||
assertThat(conversationAction,
|
||||
isConversationAction(ConversationActions.TYPE_TEXT_REPLY));
|
||||
isConversationAction(ConversationAction.TYPE_TEXT_REPLY));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,20 +524,19 @@ public class TextClassifierTest {
|
||||
};
|
||||
}
|
||||
|
||||
private static Matcher<ConversationActions.ConversationAction> isConversationAction(
|
||||
String actionType) {
|
||||
return new BaseMatcher<ConversationActions.ConversationAction>() {
|
||||
private static Matcher<ConversationAction> isConversationAction(String actionType) {
|
||||
return new BaseMatcher<ConversationAction>() {
|
||||
@Override
|
||||
public boolean matches(Object o) {
|
||||
if (!(o instanceof ConversationActions.ConversationAction)) {
|
||||
if (!(o instanceof ConversationAction)) {
|
||||
return false;
|
||||
}
|
||||
ConversationActions.ConversationAction conversationAction =
|
||||
(ConversationActions.ConversationAction) o;
|
||||
ConversationAction conversationAction =
|
||||
(ConversationAction) o;
|
||||
if (!actionType.equals(conversationAction.getType())) {
|
||||
return false;
|
||||
}
|
||||
if (ConversationActions.TYPE_TEXT_REPLY.equals(actionType)) {
|
||||
if (ConversationAction.TYPE_TEXT_REPLY.equals(actionType)) {
|
||||
if (conversationAction.getTextReply() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import android.metrics.LogMaker;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.view.textclassifier.ConversationActions;
|
||||
import android.view.textclassifier.ConversationAction;
|
||||
import android.view.textclassifier.TextClassificationContext;
|
||||
import android.view.textclassifier.TextClassifierEvent;
|
||||
import android.view.textclassifier.TextClassifierEventTronLogger;
|
||||
@@ -69,7 +69,7 @@ public class TextClassifierEventTronLoggerTest {
|
||||
new TextClassifierEvent.Builder(
|
||||
TextClassifierEvent.CATEGORY_CONVERSATION_ACTIONS,
|
||||
TextClassifierEvent.TYPE_SMART_ACTION)
|
||||
.setEntityType(ConversationActions.TYPE_CALL_PHONE)
|
||||
.setEntityType(ConversationAction.TYPE_CALL_PHONE)
|
||||
.setEventTime(EVENT_TIME)
|
||||
.setEventContext(textClassificationContext)
|
||||
.build();
|
||||
@@ -84,7 +84,7 @@ public class TextClassifierEventTronLoggerTest {
|
||||
assertThat(logMaker.getType()).isEqualTo(
|
||||
ACTION_TEXT_SELECTION_SMART_SHARE);
|
||||
assertThat(logMaker.getTaggedData(FIELD_SELECTION_ENTITY_TYPE))
|
||||
.isEqualTo(ConversationActions.TYPE_CALL_PHONE);
|
||||
.isEqualTo(ConversationAction.TYPE_CALL_PHONE);
|
||||
assertThat(logMaker.getTaggedData(FIELD_TEXT_CLASSIFIER_EVENT_TIME))
|
||||
.isEqualTo(EVENT_TIME);
|
||||
assertThat(logMaker.getPackageName()).isEqualTo(PACKAGE_NAME);
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.os.Process;
|
||||
import android.service.notification.NotificationAssistantService;
|
||||
import android.text.TextUtils;
|
||||
import android.util.LruCache;
|
||||
import android.view.textclassifier.ConversationAction;
|
||||
import android.view.textclassifier.ConversationActions;
|
||||
import android.view.textclassifier.TextClassification;
|
||||
import android.view.textclassifier.TextClassificationContext;
|
||||
@@ -65,13 +66,13 @@ public class SmartActionsHelper {
|
||||
private static final int MAX_MESSAGES_TO_EXTRACT = 5;
|
||||
private static final int MAX_RESULT_ID_TO_CACHE = 20;
|
||||
|
||||
private static final ConversationActions.TypeConfig TYPE_CONFIG =
|
||||
new ConversationActions.TypeConfig.Builder().setIncludedTypes(
|
||||
Collections.singletonList(ConversationActions.TYPE_TEXT_REPLY))
|
||||
private static final TextClassifier.EntityConfig TYPE_CONFIG =
|
||||
new TextClassifier.EntityConfig.Builder().setIncludedTypes(
|
||||
Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
|
||||
.includeTypesFromTextClassifier(false)
|
||||
.build();
|
||||
private static final List<String> HINTS =
|
||||
Collections.singletonList(ConversationActions.HINT_FOR_NOTIFICATION);
|
||||
Collections.singletonList(ConversationActions.Request.HINT_FOR_NOTIFICATION);
|
||||
|
||||
private Context mContext;
|
||||
@Nullable
|
||||
@@ -137,7 +138,7 @@ public class SmartActionsHelper {
|
||||
|
||||
ConversationActions conversationActionsResult =
|
||||
mTextClassifier.suggestConversationActions(request);
|
||||
List<ConversationActions.ConversationAction> conversationActions =
|
||||
List<ConversationAction> conversationActions =
|
||||
conversationActionsResult.getConversationActions();
|
||||
ArrayList<CharSequence> replies = conversationActions.stream()
|
||||
.map(conversationAction -> conversationAction.getTextReply())
|
||||
@@ -193,7 +194,7 @@ public class SmartActionsHelper {
|
||||
}
|
||||
TextClassifierEvent textClassifierEvent =
|
||||
createTextClassifierEventBuilder(TextClassifierEvent.TYPE_SMART_ACTION, resultId)
|
||||
.setEntityType(ConversationActions.TYPE_TEXT_REPLY)
|
||||
.setEntityType(ConversationAction.TYPE_TEXT_REPLY)
|
||||
.build();
|
||||
mTextClassifier.onTextClassifierEvent(textClassifierEvent);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.service.notification.NotificationAssistantService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.view.textclassifier.ConversationAction;
|
||||
import android.view.textclassifier.ConversationActions;
|
||||
import android.view.textclassifier.TextClassificationManager;
|
||||
import android.view.textclassifier.TextClassifier;
|
||||
@@ -65,9 +66,10 @@ public class SmartActionHelperTest {
|
||||
private static final String NOTIFICATION_KEY = "key";
|
||||
private static final String RESULT_ID = "id";
|
||||
|
||||
private static final ConversationActions.ConversationAction REPLY_ACTION =
|
||||
new ConversationActions.ConversationAction.Builder(
|
||||
ConversationActions.TYPE_TEXT_REPLY).setTextReply("Home").build();
|
||||
private static final ConversationAction REPLY_ACTION =
|
||||
new ConversationAction.Builder(ConversationAction.TYPE_TEXT_REPLY)
|
||||
.setTextReply("Home")
|
||||
.build();
|
||||
|
||||
private SmartActionsHelper mSmartActionsHelper;
|
||||
private Context mContext;
|
||||
|
||||
Reference in New Issue
Block a user