1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app.smartspace; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SuppressLint; 22 import android.annotation.SystemApi; 23 import android.app.PendingIntent; 24 import android.content.Intent; 25 import android.graphics.drawable.Icon; 26 import android.os.Bundle; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 import android.os.UserHandle; 30 import android.text.TextUtils; 31 32 import java.util.Objects; 33 34 /** 35 * A {@link SmartspaceAction} represents an action which can be taken by a user by tapping on either 36 * the title, the subtitle or on the icon. Supported instances are Intents, PendingIntents or a 37 * ShortcutInfo (by putting the ShortcutInfoId in the bundle). These actions can be called from 38 * another process or within the client process. 39 * 40 * Clients can also receive conditional Intents/PendingIntents in the extras bundle which are 41 * supposed to be fired when the conditions are met. For example, a user can invoke a dismiss/block 42 * action on a game score card but the intention is to only block the team and not the entire 43 * feature. 44 * 45 * @hide 46 */ 47 @SystemApi 48 public final class SmartspaceAction implements Parcelable { 49 50 private static final String TAG = "SmartspaceAction"; 51 52 /** A unique Id of this {@link SmartspaceAction}. */ 53 @NonNull 54 private final String mId; 55 56 /** An Icon which can be displayed in the UI. */ 57 @Nullable 58 private final Icon mIcon; 59 60 /** Title associated with an action. */ 61 @NonNull 62 private final CharSequence mTitle; 63 64 /** Subtitle associated with an action. */ 65 @Nullable 66 private final CharSequence mSubtitle; 67 68 @Nullable 69 private final CharSequence mContentDescription; 70 71 @Nullable 72 private final PendingIntent mPendingIntent; 73 74 @Nullable 75 private final Intent mIntent; 76 77 @Nullable 78 private final UserHandle mUserHandle; 79 80 @Nullable 81 private Bundle mExtras; 82 SmartspaceAction(Parcel in)83 SmartspaceAction(Parcel in) { 84 mId = in.readString(); 85 mIcon = in.readTypedObject(Icon.CREATOR); 86 mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 87 mSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 88 mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 89 mPendingIntent = in.readTypedObject(PendingIntent.CREATOR); 90 mIntent = in.readTypedObject(Intent.CREATOR); 91 mUserHandle = in.readTypedObject(UserHandle.CREATOR); 92 mExtras = in.readBundle(); 93 } 94 SmartspaceAction( @onNull String id, @Nullable Icon icon, @NonNull CharSequence title, @Nullable CharSequence subtitle, @Nullable CharSequence contentDescription, @Nullable PendingIntent pendingIntent, @Nullable Intent intent, @Nullable UserHandle userHandle, @Nullable Bundle extras)95 private SmartspaceAction( 96 @NonNull String id, 97 @Nullable Icon icon, 98 @NonNull CharSequence title, 99 @Nullable CharSequence subtitle, 100 @Nullable CharSequence contentDescription, 101 @Nullable PendingIntent pendingIntent, 102 @Nullable Intent intent, 103 @Nullable UserHandle userHandle, 104 @Nullable Bundle extras) { 105 mId = Objects.requireNonNull(id); 106 mIcon = icon; 107 mTitle = Objects.requireNonNull(title); 108 mSubtitle = subtitle; 109 mContentDescription = contentDescription; 110 mPendingIntent = pendingIntent; 111 mIntent = intent; 112 mUserHandle = userHandle; 113 mExtras = extras; 114 } 115 116 /** 117 * Returns the unique id of this object. 118 */ getId()119 public @NonNull String getId() { 120 return mId; 121 } 122 123 /** 124 * Returns an icon representing the action. 125 */ getIcon()126 public @Nullable Icon getIcon() { 127 return mIcon; 128 } 129 130 /** 131 * Returns a title representing the action. 132 */ getTitle()133 public @NonNull CharSequence getTitle() { 134 return mTitle; 135 } 136 137 /** 138 * Returns a subtitle representing the action. 139 */ getSubtitle()140 public @Nullable CharSequence getSubtitle() { 141 return mSubtitle; 142 } 143 144 /** 145 * Returns a content description representing the action. 146 */ getContentDescription()147 public @Nullable CharSequence getContentDescription() { 148 return mContentDescription; 149 } 150 151 /** 152 * Returns the action intent. 153 */ getPendingIntent()154 public @Nullable PendingIntent getPendingIntent() { 155 return mPendingIntent; 156 } 157 158 /** 159 * Returns the intent. 160 */ getIntent()161 public @Nullable Intent getIntent() { 162 return mIntent; 163 } 164 165 /** 166 * Returns the user handle. 167 */ getUserHandle()168 public @Nullable UserHandle getUserHandle() { 169 return mUserHandle; 170 } 171 172 /** 173 * Returns the extra bundle for this object. 174 */ 175 @SuppressLint("NullableCollection") getExtras()176 public @Nullable Bundle getExtras() { 177 return mExtras; 178 } 179 180 @Override equals(Object o)181 public boolean equals(Object o) { 182 if (this == o) return true; 183 if (!(o instanceof SmartspaceAction)) return false; 184 SmartspaceAction that = (SmartspaceAction) o; 185 return mId.equals(that.mId); 186 } 187 188 @Override hashCode()189 public int hashCode() { 190 return Objects.hash(mId); 191 } 192 193 @Override describeContents()194 public int describeContents() { 195 return 0; 196 } 197 198 @Override writeToParcel(@onNull Parcel out, int flags)199 public void writeToParcel(@NonNull Parcel out, int flags) { 200 out.writeString(mId); 201 out.writeTypedObject(mIcon, flags); 202 TextUtils.writeToParcel(mTitle, out, flags); 203 TextUtils.writeToParcel(mSubtitle, out, flags); 204 TextUtils.writeToParcel(mContentDescription, out, flags); 205 out.writeTypedObject(mPendingIntent, flags); 206 out.writeTypedObject(mIntent, flags); 207 out.writeTypedObject(mUserHandle, flags); 208 out.writeBundle(mExtras); 209 } 210 211 @Override toString()212 public String toString() { 213 return "SmartspaceAction{" 214 + "mId='" + mId + '\'' 215 + ", mIcon=" + mIcon 216 + ", mTitle=" + mTitle 217 + ", mSubtitle=" + mSubtitle 218 + ", mContentDescription=" + mContentDescription 219 + ", mPendingIntent=" + mPendingIntent 220 + ", mIntent=" + mIntent 221 + ", mUserHandle=" + mUserHandle 222 + ", mExtras=" + mExtras 223 + '}'; 224 } 225 226 public static final @NonNull Creator<SmartspaceAction> CREATOR = 227 new Creator<SmartspaceAction>() { 228 public SmartspaceAction createFromParcel(Parcel in) { 229 return new SmartspaceAction(in); 230 } 231 public SmartspaceAction[] newArray(int size) { 232 return new SmartspaceAction[size]; 233 } 234 }; 235 236 /** 237 * A builder for Smartspace action object. 238 * 239 * @hide 240 */ 241 @SystemApi 242 public static final class Builder { 243 @NonNull 244 private String mId; 245 246 @Nullable 247 private Icon mIcon; 248 249 @NonNull 250 private CharSequence mTitle; 251 252 @Nullable 253 private CharSequence mSubtitle; 254 255 @Nullable 256 private CharSequence mContentDescription; 257 258 @Nullable 259 private PendingIntent mPendingIntent; 260 261 @Nullable 262 private Intent mIntent; 263 264 @Nullable 265 private UserHandle mUserHandle; 266 267 @Nullable 268 private Bundle mExtras; 269 270 /** 271 * Id and title are required. 272 */ Builder(@onNull String id, @NonNull String title)273 public Builder(@NonNull String id, @NonNull String title) { 274 mId = Objects.requireNonNull(id); 275 mTitle = Objects.requireNonNull(title); 276 } 277 278 /** 279 * Sets the icon. 280 */ 281 @NonNull setIcon( @ullable Icon icon)282 public Builder setIcon( 283 @Nullable Icon icon) { 284 mIcon = icon; 285 return this; 286 } 287 288 /** 289 * Sets the subtitle. 290 */ 291 @NonNull setSubtitle( @ullable CharSequence subtitle)292 public Builder setSubtitle( 293 @Nullable CharSequence subtitle) { 294 mSubtitle = subtitle; 295 return this; 296 } 297 298 /** 299 * Sets the content description. 300 */ 301 @NonNull setContentDescription( @ullable CharSequence contentDescription)302 public Builder setContentDescription( 303 @Nullable CharSequence contentDescription) { 304 mContentDescription = contentDescription; 305 return this; 306 } 307 308 /** 309 * Sets the pending intent. 310 */ 311 @NonNull setPendingIntent(@ullable PendingIntent pendingIntent)312 public Builder setPendingIntent(@Nullable PendingIntent pendingIntent) { 313 mPendingIntent = pendingIntent; 314 return this; 315 } 316 317 /** 318 * Sets the user handle. 319 */ 320 @NonNull setUserHandle(@ullable UserHandle userHandle)321 public Builder setUserHandle(@Nullable UserHandle userHandle) { 322 mUserHandle = userHandle; 323 return this; 324 } 325 326 /** 327 * Sets the intent. 328 */ 329 @NonNull setIntent(@ullable Intent intent)330 public Builder setIntent(@Nullable Intent intent) { 331 mIntent = intent; 332 return this; 333 } 334 335 /** 336 * Sets the extra. 337 */ 338 @NonNull setExtras(@uppressLintR) @ullable Bundle extras)339 public Builder setExtras(@SuppressLint("NullableCollection") @Nullable Bundle extras) { 340 mExtras = extras; 341 return this; 342 } 343 344 /** 345 * Builds a new SmartspaceAction instance. 346 * 347 * @throws IllegalStateException if no target is set 348 */ 349 @NonNull build()350 public SmartspaceAction build() { 351 if (mIcon != null) { 352 mIcon.convertToAshmem(); 353 } 354 355 return new SmartspaceAction(mId, mIcon, mTitle, mSubtitle, mContentDescription, 356 mPendingIntent, mIntent, mUserHandle, mExtras); 357 } 358 } 359 } 360