Merge "Cleanup TextClassifier APIs"

This commit is contained in:
TreeHugger Robot
2019-01-15 10:49:13 +00:00
committed by Android (Google) Code Review
10 changed files with 525 additions and 547 deletions

View File

@@ -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();

View 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());
}
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;