1 /* 2 * Copyright (C) 2022 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.uitemplatedata; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.app.smartspace.SmartspaceTarget; 23 import android.app.smartspace.SmartspaceUtils; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import java.util.List; 28 import java.util.Objects; 29 30 /** 31 * Holds all the relevant data needed to render a Smartspace card with the carousel Ui Template. 32 * 33 * This template will add a sub-card displaying a list of carousel items within the default-template 34 * card: 35 * <ul> 36 * <li> carouselItem1, carouselItem2, carouselItem3... </li> 37 * </ul> 38 * 39 * @hide 40 */ 41 @SystemApi 42 public final class CarouselTemplateData extends BaseTemplateData { 43 44 /** Lists of {@link CarouselItem}. */ 45 @NonNull 46 private final List<CarouselItem> mCarouselItems; 47 48 /** Tap action for the entire carousel secondary card, including the blank space */ 49 @Nullable 50 private final TapAction mCarouselAction; 51 CarouselTemplateData(@onNull Parcel in)52 CarouselTemplateData(@NonNull Parcel in) { 53 super(in); 54 mCarouselItems = in.createTypedArrayList(CarouselItem.CREATOR); 55 mCarouselAction = in.readTypedObject(TapAction.CREATOR); 56 } 57 CarouselTemplateData(@martspaceTarget.UiTemplateType int templateType, @Nullable SubItemInfo primaryItem, @Nullable SubItemInfo subtitleItem, @Nullable SubItemInfo subtitleSupplementalItem, @Nullable SubItemInfo supplementalLineItem, @Nullable SubItemInfo supplementalAlarmItem, int layoutWeight, @NonNull List<CarouselItem> carouselItems, @Nullable TapAction carouselAction)58 private CarouselTemplateData(@SmartspaceTarget.UiTemplateType int templateType, 59 @Nullable SubItemInfo primaryItem, 60 @Nullable SubItemInfo subtitleItem, 61 @Nullable SubItemInfo subtitleSupplementalItem, 62 @Nullable SubItemInfo supplementalLineItem, 63 @Nullable SubItemInfo supplementalAlarmItem, 64 int layoutWeight, 65 @NonNull List<CarouselItem> carouselItems, 66 @Nullable TapAction carouselAction) { 67 super(templateType, primaryItem, subtitleItem, subtitleSupplementalItem, 68 supplementalLineItem, supplementalAlarmItem, layoutWeight); 69 70 mCarouselItems = carouselItems; 71 mCarouselAction = carouselAction; 72 } 73 74 /** Returns the list of {@link CarouselItem}. Can be empty if not being set. */ 75 @NonNull getCarouselItems()76 public List<CarouselItem> getCarouselItems() { 77 return mCarouselItems; 78 } 79 80 /** Returns the card's tap action. */ 81 @Nullable getCarouselAction()82 public TapAction getCarouselAction() { 83 return mCarouselAction; 84 } 85 86 /** 87 * @see Parcelable.Creator 88 */ 89 @NonNull 90 public static final Creator<CarouselTemplateData> CREATOR = 91 new Creator<CarouselTemplateData>() { 92 @Override 93 public CarouselTemplateData createFromParcel(Parcel in) { 94 return new CarouselTemplateData(in); 95 } 96 97 @Override 98 public CarouselTemplateData[] newArray(int size) { 99 return new CarouselTemplateData[size]; 100 } 101 }; 102 103 @Override describeContents()104 public int describeContents() { 105 return 0; 106 } 107 108 @Override writeToParcel(@onNull Parcel out, int flags)109 public void writeToParcel(@NonNull Parcel out, int flags) { 110 super.writeToParcel(out, flags); 111 out.writeTypedList(mCarouselItems); 112 out.writeTypedObject(mCarouselAction, flags); 113 } 114 115 116 @Override equals(Object o)117 public boolean equals(Object o) { 118 if (this == o) return true; 119 if (!(o instanceof CarouselTemplateData)) return false; 120 if (!super.equals(o)) return false; 121 CarouselTemplateData that = (CarouselTemplateData) o; 122 return mCarouselItems.equals(that.mCarouselItems) && Objects.equals(mCarouselAction, 123 that.mCarouselAction); 124 } 125 126 @Override hashCode()127 public int hashCode() { 128 return Objects.hash(super.hashCode(), mCarouselItems, mCarouselAction); 129 } 130 131 @Override toString()132 public String toString() { 133 return super.toString() + " + SmartspaceCarouselUiTemplateData{" 134 + "mCarouselItems=" + mCarouselItems 135 + ", mCarouselActions=" + mCarouselAction 136 + '}'; 137 } 138 139 /** 140 * A builder for {@link CarouselTemplateData} object. 141 * 142 * @hide 143 */ 144 @SystemApi 145 public static final class Builder extends BaseTemplateData.Builder { 146 147 private final List<CarouselItem> mCarouselItems; 148 private TapAction mCarouselAction; 149 150 /** 151 * A builder for {@link CarouselTemplateData}. 152 */ Builder(@onNull List<CarouselItem> carouselItems)153 public Builder(@NonNull List<CarouselItem> carouselItems) { 154 super(SmartspaceTarget.UI_TEMPLATE_CAROUSEL); 155 mCarouselItems = Objects.requireNonNull(carouselItems); 156 } 157 158 /** 159 * Sets the card tap action. 160 */ 161 @NonNull setCarouselAction(@onNull TapAction carouselAction)162 public Builder setCarouselAction(@NonNull TapAction carouselAction) { 163 mCarouselAction = carouselAction; 164 return this; 165 } 166 167 /** 168 * Builds a new {@link CarouselTemplateData} instance. 169 * 170 * @throws IllegalStateException if the carousel data is invalid. 171 */ 172 @NonNull build()173 public CarouselTemplateData build() { 174 if (mCarouselItems.isEmpty()) { 175 throw new IllegalStateException("Carousel data is empty"); 176 } 177 178 return new CarouselTemplateData(getTemplateType(), getPrimaryItem(), 179 getSubtitleItem(), getSubtitleSupplemtnalItem(), 180 getSupplementalLineItem(), getSupplementalAlarmItem(), getLayoutWeight(), 181 mCarouselItems, mCarouselAction); 182 } 183 } 184 185 /** 186 * Holds all the relevant data needed to render a carousel item. 187 * 188 * <ul> 189 * <li> upper text </li> 190 * <li> image </li> 191 * <li> lower text </li> 192 * </ul> 193 */ 194 public static final class CarouselItem implements Parcelable { 195 196 /** Text which is above the image item. */ 197 @Nullable 198 private final Text mUpperText; 199 200 /** Image item. Can be empty. */ 201 @Nullable 202 private final Icon mImage; 203 204 /** Text which is under the image item. */ 205 @Nullable 206 private final Text mLowerText; 207 208 /** 209 * Tap action for this {@link CarouselItem} instance. {@code mCarouselAction} is used if not 210 * being set. 211 */ 212 @Nullable 213 private final TapAction mTapAction; 214 CarouselItem(@onNull Parcel in)215 CarouselItem(@NonNull Parcel in) { 216 mUpperText = in.readTypedObject(Text.CREATOR); 217 mImage = in.readTypedObject(Icon.CREATOR); 218 mLowerText = in.readTypedObject(Text.CREATOR); 219 mTapAction = in.readTypedObject(TapAction.CREATOR); 220 } 221 CarouselItem(@ullable Text upperText, @Nullable Icon image, @Nullable Text lowerText, @Nullable TapAction tapAction)222 private CarouselItem(@Nullable Text upperText, @Nullable Icon image, 223 @Nullable Text lowerText, @Nullable TapAction tapAction) { 224 mUpperText = upperText; 225 mImage = image; 226 mLowerText = lowerText; 227 mTapAction = tapAction; 228 } 229 230 @Nullable getUpperText()231 public Text getUpperText() { 232 return mUpperText; 233 } 234 235 @Nullable getImage()236 public Icon getImage() { 237 return mImage; 238 } 239 240 @Nullable getLowerText()241 public Text getLowerText() { 242 return mLowerText; 243 } 244 245 @Nullable getTapAction()246 public TapAction getTapAction() { 247 return mTapAction; 248 } 249 250 /** 251 * @see Parcelable.Creator 252 */ 253 @NonNull 254 public static final Creator<CarouselItem> CREATOR = 255 new Creator<CarouselItem>() { 256 @Override 257 public CarouselItem createFromParcel(Parcel in) { 258 return new CarouselItem(in); 259 } 260 261 @Override 262 public CarouselItem[] newArray(int size) { 263 return new CarouselItem[size]; 264 } 265 }; 266 267 @Override describeContents()268 public int describeContents() { 269 return 0; 270 } 271 272 @Override writeToParcel(@onNull Parcel out, int flags)273 public void writeToParcel(@NonNull Parcel out, int flags) { 274 out.writeTypedObject(mUpperText, flags); 275 out.writeTypedObject(mImage, flags); 276 out.writeTypedObject(mLowerText, flags); 277 out.writeTypedObject(mTapAction, flags); 278 } 279 280 @Override equals(Object o)281 public boolean equals(Object o) { 282 if (this == o) return true; 283 if (!(o instanceof CarouselItem)) return false; 284 CarouselItem that = (CarouselItem) o; 285 return SmartspaceUtils.isEqual(mUpperText, that.mUpperText) && Objects.equals( 286 mImage, 287 that.mImage) && SmartspaceUtils.isEqual(mLowerText, that.mLowerText) 288 && Objects.equals(mTapAction, that.mTapAction); 289 } 290 291 @Override hashCode()292 public int hashCode() { 293 return Objects.hash(mUpperText, mImage, mLowerText, mTapAction); 294 } 295 296 @Override toString()297 public String toString() { 298 return "CarouselItem{" 299 + "mUpperText=" + mUpperText 300 + ", mImage=" + mImage 301 + ", mLowerText=" + mLowerText 302 + ", mTapAction=" + mTapAction 303 + '}'; 304 } 305 306 /** 307 * A builder for {@link CarouselItem} object. 308 * 309 * @hide 310 */ 311 @SystemApi 312 public static final class Builder { 313 314 private Text mUpperText; 315 private Icon mImage; 316 private Text mLowerText; 317 private TapAction mTapAction; 318 319 /** 320 * Sets the upper text. 321 */ 322 @NonNull setUpperText(@ullable Text upperText)323 public Builder setUpperText(@Nullable Text upperText) { 324 mUpperText = upperText; 325 return this; 326 } 327 328 /** 329 * Sets the image. 330 */ 331 @NonNull setImage(@ullable Icon image)332 public Builder setImage(@Nullable Icon image) { 333 mImage = image; 334 return this; 335 } 336 337 338 /** 339 * Sets the lower text. 340 */ 341 @NonNull setLowerText(@ullable Text lowerText)342 public Builder setLowerText(@Nullable Text lowerText) { 343 mLowerText = lowerText; 344 return this; 345 } 346 347 /** 348 * Sets the tap action. 349 */ 350 @NonNull setTapAction(@ullable TapAction tapAction)351 public Builder setTapAction(@Nullable TapAction tapAction) { 352 mTapAction = tapAction; 353 return this; 354 } 355 356 /** 357 * Builds a new CarouselItem instance. 358 * 359 * @throws IllegalStateException if all the rendering data is empty. 360 */ 361 @NonNull build()362 public CarouselItem build() { 363 if (SmartspaceUtils.isEmpty(mUpperText) && mImage == null 364 && SmartspaceUtils.isEmpty( 365 mLowerText)) { 366 throw new IllegalStateException("Carousel data is empty"); 367 } 368 return new CarouselItem(mUpperText, mImage, mLowerText, mTapAction); 369 } 370 } 371 } 372 } 373