1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.view.textclassifier; 17 18 import static java.lang.annotation.RetentionPolicy.SOURCE; 19 20 import android.annotation.FloatRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.StringDef; 24 import android.app.RemoteAction; 25 import android.os.Bundle; 26 import android.os.Parcel; 27 import android.os.Parcelable; 28 29 import java.lang.annotation.Retention; 30 import java.util.Objects; 31 32 /** Represents the action suggested by a {@link TextClassifier} on a given conversation. */ 33 public final class ConversationAction implements Parcelable { 34 35 /** @hide */ 36 @Retention(SOURCE) 37 @StringDef( 38 value = { 39 TYPE_VIEW_CALENDAR, 40 TYPE_VIEW_MAP, 41 TYPE_TRACK_FLIGHT, 42 TYPE_OPEN_URL, 43 TYPE_SEND_SMS, 44 TYPE_CALL_PHONE, 45 TYPE_SEND_EMAIL, 46 TYPE_TEXT_REPLY, 47 TYPE_CREATE_REMINDER, 48 TYPE_SHARE_LOCATION 49 }, 50 prefix = "TYPE_") 51 public @interface ActionType {} 52 53 /** 54 * Indicates an action to view a calendar at a specified time. 55 */ 56 public static final String TYPE_VIEW_CALENDAR = "view_calendar"; 57 /** 58 * Indicates an action to view the map at a specified location. 59 */ 60 public static final String TYPE_VIEW_MAP = "view_map"; 61 /** 62 * Indicates an action to track a flight. 63 */ 64 public static final String TYPE_TRACK_FLIGHT = "track_flight"; 65 /** 66 * Indicates an action to open an URL. 67 */ 68 public static final String TYPE_OPEN_URL = "open_url"; 69 /** 70 * Indicates an action to send a SMS. 71 */ 72 public static final String TYPE_SEND_SMS = "send_sms"; 73 /** 74 * Indicates an action to call a phone number. 75 */ 76 public static final String TYPE_CALL_PHONE = "call_phone"; 77 /** 78 * Indicates an action to send an email. 79 */ 80 public static final String TYPE_SEND_EMAIL = "send_email"; 81 /** 82 * Indicates an action to reply with a text message. 83 */ 84 public static final String TYPE_TEXT_REPLY = "text_reply"; 85 /** 86 * Indicates an action to create a reminder. 87 */ 88 public static final String TYPE_CREATE_REMINDER = "create_reminder"; 89 /** 90 * Indicates an action to reply with a location. 91 */ 92 public static final String TYPE_SHARE_LOCATION = "share_location"; 93 94 // TODO: Make this public API 95 /** @hide **/ 96 public static final String TYPE_ADD_CONTACT = "add_contact"; 97 98 // TODO: Make this public API 99 /** @hide **/ 100 public static final String TYPE_COPY = "copy"; 101 102 public static final @NonNull Creator<ConversationAction> CREATOR = 103 new Creator<ConversationAction>() { 104 @Override 105 public ConversationAction createFromParcel(Parcel in) { 106 return new ConversationAction(in); 107 } 108 109 @Override 110 public ConversationAction[] newArray(int size) { 111 return new ConversationAction[size]; 112 } 113 }; 114 115 @NonNull 116 @ActionType 117 private final String mType; 118 @NonNull 119 private final CharSequence mTextReply; 120 @Nullable 121 private final RemoteAction mAction; 122 123 @FloatRange(from = 0, to = 1) 124 private final float mScore; 125 126 @NonNull 127 private final Bundle mExtras; 128 ConversationAction( @onNull String type, @Nullable RemoteAction action, @Nullable CharSequence textReply, float score, @NonNull Bundle extras)129 private ConversationAction( 130 @NonNull String type, 131 @Nullable RemoteAction action, 132 @Nullable CharSequence textReply, 133 float score, 134 @NonNull Bundle extras) { 135 mType = Objects.requireNonNull(type); 136 mAction = action; 137 mTextReply = textReply; 138 mScore = score; 139 mExtras = Objects.requireNonNull(extras); 140 } 141 ConversationAction(Parcel in)142 private ConversationAction(Parcel in) { 143 mType = in.readString(); 144 mAction = in.readParcelable(null, android.app.RemoteAction.class); 145 mTextReply = in.readCharSequence(); 146 mScore = in.readFloat(); 147 mExtras = in.readBundle(); 148 } 149 150 @Override writeToParcel(Parcel parcel, int flags)151 public void writeToParcel(Parcel parcel, int flags) { 152 parcel.writeString(mType); 153 parcel.writeParcelable(mAction, flags); 154 parcel.writeCharSequence(mTextReply); 155 parcel.writeFloat(mScore); 156 parcel.writeBundle(mExtras); 157 } 158 159 @Override describeContents()160 public int describeContents() { 161 return 0; 162 } 163 164 /** Returns the type of this action, for example, {@link #TYPE_VIEW_CALENDAR}. */ 165 @NonNull 166 @ActionType getType()167 public String getType() { 168 return mType; 169 } 170 171 /** 172 * Returns a RemoteAction object, which contains the icon, label and a PendingIntent, for 173 * the specified action type. 174 */ 175 @Nullable getAction()176 public RemoteAction getAction() { 177 return mAction; 178 } 179 180 /** 181 * Returns the confidence score for the specified action. The value ranges from 0 (low 182 * confidence) to 1 (high confidence). 183 */ 184 @FloatRange(from = 0, to = 1) getConfidenceScore()185 public float getConfidenceScore() { 186 return mScore; 187 } 188 189 /** 190 * Returns the text reply that could be sent as a reply to the given conversation. 191 * <p> 192 * This is only available when the type of the action is {@link #TYPE_TEXT_REPLY}. 193 */ 194 @Nullable getTextReply()195 public CharSequence getTextReply() { 196 return mTextReply; 197 } 198 199 /** 200 * Returns the extended data related to this conversation action. 201 * 202 * <p><b>NOTE: </b>Do not modify this bundle. 203 */ 204 @NonNull getExtras()205 public Bundle getExtras() { 206 return mExtras; 207 } 208 209 /** @hide */ toBuilder()210 public Builder toBuilder() { 211 return new Builder(mType) 212 .setTextReply(mTextReply) 213 .setAction(mAction) 214 .setConfidenceScore(mScore) 215 .setExtras(mExtras); 216 } 217 218 /** Builder class to construct {@link ConversationAction}. */ 219 public static final class Builder { 220 @Nullable 221 @ActionType 222 private String mType; 223 @Nullable 224 private RemoteAction mAction; 225 @Nullable 226 private CharSequence mTextReply; 227 private float mScore; 228 @Nullable 229 private Bundle mExtras; 230 Builder(@onNull @ctionType String actionType)231 public Builder(@NonNull @ActionType String actionType) { 232 mType = Objects.requireNonNull(actionType); 233 } 234 235 /** 236 * Sets an action that may be performed on the given conversation. 237 */ 238 @NonNull setAction(@ullable RemoteAction action)239 public Builder setAction(@Nullable RemoteAction action) { 240 mAction = action; 241 return this; 242 } 243 244 /** 245 * Sets a text reply that may be performed on the given conversation. 246 */ 247 @NonNull setTextReply(@ullable CharSequence textReply)248 public Builder setTextReply(@Nullable CharSequence textReply) { 249 mTextReply = textReply; 250 return this; 251 } 252 253 /** Sets the confident score. */ 254 @NonNull setConfidenceScore(@loatRangefrom = 0, to = 1) float score)255 public Builder setConfidenceScore(@FloatRange(from = 0, to = 1) float score) { 256 mScore = score; 257 return this; 258 } 259 260 /** 261 * Sets the extended data for the conversation action object. 262 */ 263 @NonNull setExtras(@ullable Bundle extras)264 public Builder setExtras(@Nullable Bundle extras) { 265 mExtras = extras; 266 return this; 267 } 268 269 /** Builds the {@link ConversationAction} object. */ 270 @NonNull build()271 public ConversationAction build() { 272 return new ConversationAction( 273 mType, 274 mAction, 275 mTextReply, 276 mScore, 277 mExtras == null ? Bundle.EMPTY : mExtras); 278 } 279 } 280 } 281