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