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 package android.app.smartspace;
17 
18 import android.annotation.CurrentTimeMillisLong;
19 import android.annotation.FlaggedApi;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 import android.app.smartspace.flags.Flags;
25 import android.app.smartspace.uitemplatedata.BaseTemplateData;
26 import android.appwidget.AppWidgetProviderInfo;
27 import android.content.ComponentName;
28 import android.net.Uri;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 import android.os.UserHandle;
32 import android.widget.RemoteViews;
33 
34 import java.lang.annotation.Retention;
35 import java.lang.annotation.RetentionPolicy;
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.Objects;
39 
40 /**
41  * A {@link SmartspaceTarget} is a data class which holds all properties necessary to inflate a
42  * smartspace card. It contains data and related metadata which is supposed to be utilized by
43  * smartspace clients based on their own UI/UX requirements. Some of the properties have
44  * {@link SmartspaceAction} as their type because they can have associated actions.
45  *
46  * <p><b>NOTE: </b>
47  * If either {@link mRemoteViews} or {@link mWidget} is set, it should be preferred over all
48  * other properties. (An exception is thrown if both are set.)
49  * Else, if {@link mSliceUri} is set, it should be preferred over all other data properties.
50  * Otherwise, the instance should be treated as a data object.
51  *
52  * @hide
53  */
54 @SystemApi
55 public final class SmartspaceTarget implements Parcelable {
56 
57     /** A unique Id for an instance of {@link SmartspaceTarget}. */
58     @NonNull
59     private final String mSmartspaceTargetId;
60 
61     /** A {@link SmartspaceAction} for the header in the Smartspace card. */
62     @Nullable
63     private final SmartspaceAction mHeaderAction;
64 
65     /** A {@link SmartspaceAction} for the base action in the Smartspace card. */
66     @Nullable
67     private final SmartspaceAction mBaseAction;
68 
69     /** A timestamp indicating when the card was created. */
70     @CurrentTimeMillisLong
71     private final long mCreationTimeMillis;
72 
73     /**
74      * A timestamp indicating when the card should be removed from view, in case the service
75      * disconnects or restarts.
76      */
77     @CurrentTimeMillisLong
78     private final long mExpiryTimeMillis;
79 
80     /** A score assigned to a target. */
81     private final float mScore;
82 
83     /** A {@link List<SmartspaceAction>} containing all action chips. */
84     @NonNull
85     private final List<SmartspaceAction> mActionChips;
86 
87     /** A {@link List<SmartspaceAction>} containing all icons for the grid. */
88     @NonNull
89     private final List<SmartspaceAction> mIconGrid;
90 
91     /**
92      * {@link FeatureType} indicating the feature type of this card.
93      *
94      * @see FeatureType
95      */
96     @FeatureType
97     private final int mFeatureType;
98 
99     /**
100      * Indicates whether the content is sensitive. Certain UI surfaces may choose to skip rendering
101      * real content until the device is unlocked.
102      */
103     private final boolean mSensitive;
104 
105     /** Indicating if the UI should show this target in its expanded state. */
106     private final boolean mShouldShowExpanded;
107 
108     /** A Notification key if the target was generated using a notification. */
109     @Nullable
110     private final String mSourceNotificationKey;
111 
112     /** {@link ComponentName} for this target. */
113     @NonNull
114     private final ComponentName mComponentName;
115 
116     /** {@link UserHandle} for this target. */
117     @NonNull
118     private final UserHandle mUserHandle;
119 
120     /**
121      * Target Id of other {@link SmartspaceTarget}s if it is associated with this target. This
122      * association is added to tell the UI that a card would be more useful if displayed with the
123      * associated smartspace target. This field is supposed to be taken as a suggestion and the
124      * association can be ignored based on the situation in the UI. It is possible to have a one way
125      * card association. In other words, Card B can be associated with Card A but not the other way
126      * around.
127      */
128     @Nullable
129     private final String mAssociatedSmartspaceTargetId;
130 
131     /** {@link Uri} Slice Uri if this target is a slice. */
132     @Nullable
133     private final Uri mSliceUri;
134 
135     /** {@link AppWidgetProviderInfo} if this target is a widget. */
136     @Nullable
137     private final AppWidgetProviderInfo mWidget;
138 
139     @Nullable
140     private final RemoteViews mRemoteViews;
141 
142     @Nullable
143     private final BaseTemplateData mTemplateData;
144 
145     public static final int FEATURE_UNDEFINED = 0;
146     public static final int FEATURE_WEATHER = 1;
147     public static final int FEATURE_CALENDAR = 2;
148     public static final int FEATURE_COMMUTE_TIME = 3;
149     public static final int FEATURE_FLIGHT = 4;
150     public static final int FEATURE_TIPS = 5;
151     public static final int FEATURE_REMINDER = 6;
152     public static final int FEATURE_ALARM = 7;
153     public static final int FEATURE_ONBOARDING = 8;
154     public static final int FEATURE_SPORTS = 9;
155     public static final int FEATURE_WEATHER_ALERT = 10;
156     public static final int FEATURE_CONSENT = 11;
157     public static final int FEATURE_STOCK_PRICE_CHANGE = 12;
158     public static final int FEATURE_SHOPPING_LIST = 13;
159     public static final int FEATURE_LOYALTY_CARD = 14;
160     public static final int FEATURE_MEDIA = 15;
161     public static final int FEATURE_BEDTIME_ROUTINE = 16;
162     public static final int FEATURE_FITNESS_TRACKING = 17;
163     public static final int FEATURE_ETA_MONITORING = 18;
164     public static final int FEATURE_MISSED_CALL = 19;
165     public static final int FEATURE_PACKAGE_TRACKING = 20;
166     public static final int FEATURE_TIMER = 21;
167     public static final int FEATURE_STOPWATCH = 22;
168     public static final int FEATURE_UPCOMING_ALARM = 23;
169     public static final int FEATURE_GAS_STATION_PAYMENT = 24;
170     public static final int FEATURE_PAIRED_DEVICE_STATE = 25;
171     public static final int FEATURE_DRIVING_MODE = 26;
172     public static final int FEATURE_SLEEP_SUMMARY = 27;
173     public static final int FEATURE_FLASHLIGHT = 28;
174     public static final int FEATURE_TIME_TO_LEAVE = 29;
175     public static final int FEATURE_DOORBELL = 30;
176     public static final int FEATURE_MEDIA_RESUME = 31;
177     public static final int FEATURE_CROSS_DEVICE_TIMER = 32;
178     public static final int FEATURE_SEVERE_WEATHER_ALERT = 33;
179     public static final int FEATURE_HOLIDAY_ALARM = 34;
180     public static final int FEATURE_SAFETY_CHECK = 35;
181     public static final int FEATURE_MEDIA_HEADS_UP = 36;
182     public static final int FEATURE_STEP_COUNTING = 37;
183     public static final int FEATURE_EARTHQUAKE_ALERT = 38;
184     public static final int FEATURE_STEP_DATE = 39; // This represents a DATE. "STEP" is a typo.
185     public static final int FEATURE_BLAZE_BUILD_PROGRESS = 40;
186     public static final int FEATURE_EARTHQUAKE_OCCURRED = 41;
187 
188     /**
189      * @hide
190      */
191     @IntDef(prefix = {"FEATURE_"}, value = {
192             FEATURE_UNDEFINED,
193             FEATURE_WEATHER,
194             FEATURE_CALENDAR,
195             FEATURE_COMMUTE_TIME,
196             FEATURE_FLIGHT,
197             FEATURE_TIPS,
198             FEATURE_REMINDER,
199             FEATURE_ALARM,
200             FEATURE_ONBOARDING,
201             FEATURE_SPORTS,
202             FEATURE_WEATHER_ALERT,
203             FEATURE_CONSENT,
204             FEATURE_STOCK_PRICE_CHANGE,
205             FEATURE_SHOPPING_LIST,
206             FEATURE_LOYALTY_CARD,
207             FEATURE_MEDIA,
208             FEATURE_BEDTIME_ROUTINE,
209             FEATURE_FITNESS_TRACKING,
210             FEATURE_ETA_MONITORING,
211             FEATURE_MISSED_CALL,
212             FEATURE_PACKAGE_TRACKING,
213             FEATURE_TIMER,
214             FEATURE_STOPWATCH,
215             FEATURE_UPCOMING_ALARM,
216             FEATURE_GAS_STATION_PAYMENT,
217             FEATURE_PAIRED_DEVICE_STATE,
218             FEATURE_DRIVING_MODE,
219             FEATURE_SLEEP_SUMMARY,
220             FEATURE_FLASHLIGHT,
221             FEATURE_TIME_TO_LEAVE,
222             FEATURE_DOORBELL,
223             FEATURE_MEDIA_RESUME,
224             FEATURE_CROSS_DEVICE_TIMER,
225             FEATURE_SEVERE_WEATHER_ALERT,
226             FEATURE_HOLIDAY_ALARM,
227             FEATURE_SAFETY_CHECK,
228             FEATURE_MEDIA_HEADS_UP,
229             FEATURE_STEP_COUNTING,
230             FEATURE_EARTHQUAKE_ALERT,
231             FEATURE_STEP_DATE,
232             FEATURE_BLAZE_BUILD_PROGRESS,
233             FEATURE_EARTHQUAKE_OCCURRED
234     })
235     @Retention(RetentionPolicy.SOURCE)
236     public @interface FeatureType {
237     }
238 
239     public static final int UI_TEMPLATE_UNDEFINED = 0;
240     // Default template whose data is represented by {@link BaseTemplateData}. The default
241     // template is also a base card for the other types of templates.
242     public static final int UI_TEMPLATE_DEFAULT = 1;
243     // Sub-image template whose data is represented by {@link SubImageTemplateData}
244     public static final int UI_TEMPLATE_SUB_IMAGE = 2;
245     // Sub-list template whose data is represented by {@link SubListTemplateData}
246     public static final int UI_TEMPLATE_SUB_LIST = 3;
247     // Carousel template whose data is represented by {@link CarouselTemplateData}
248     public static final int UI_TEMPLATE_CAROUSEL = 4;
249     // Head-to-head template whose data is represented by {@link HeadToHeadTemplateData}
250     public static final int UI_TEMPLATE_HEAD_TO_HEAD = 5;
251     // Combined-cards template whose data is represented by {@link CombinedCardsTemplateData}
252     public static final int UI_TEMPLATE_COMBINED_CARDS = 6;
253     // Sub-card template whose data is represented by {@link SubCardTemplateData}
254     public static final int UI_TEMPLATE_SUB_CARD = 7;
255     // Reserved: 8
256     // Template type used by non-UI template features for sending logging information in the
257     // base template data. This should not be used for UI template features.
258     // public static final int UI_TEMPLATE_LOGGING_ONLY = 8;
259 
260     /**
261      * The types of the Smartspace ui templates.
262      *
263      * @hide
264      */
265     @IntDef(prefix = {"UI_TEMPLATE_"}, value = {
266             UI_TEMPLATE_UNDEFINED,
267             UI_TEMPLATE_DEFAULT,
268             UI_TEMPLATE_SUB_IMAGE,
269             UI_TEMPLATE_SUB_LIST,
270             UI_TEMPLATE_CAROUSEL,
271             UI_TEMPLATE_HEAD_TO_HEAD,
272             UI_TEMPLATE_COMBINED_CARDS,
273             UI_TEMPLATE_SUB_CARD
274     })
275     @Retention(RetentionPolicy.SOURCE)
276     public @interface UiTemplateType {
277     }
278 
SmartspaceTarget(Parcel in)279     private SmartspaceTarget(Parcel in) {
280         this.mSmartspaceTargetId = in.readString();
281         this.mHeaderAction = in.readTypedObject(SmartspaceAction.CREATOR);
282         this.mBaseAction = in.readTypedObject(SmartspaceAction.CREATOR);
283         this.mCreationTimeMillis = in.readLong();
284         this.mExpiryTimeMillis = in.readLong();
285         this.mScore = in.readFloat();
286         this.mActionChips = in.createTypedArrayList(SmartspaceAction.CREATOR);
287         this.mIconGrid = in.createTypedArrayList(SmartspaceAction.CREATOR);
288         this.mFeatureType = in.readInt();
289         this.mSensitive = in.readBoolean();
290         this.mShouldShowExpanded = in.readBoolean();
291         this.mSourceNotificationKey = in.readString();
292         this.mComponentName = in.readTypedObject(ComponentName.CREATOR);
293         this.mUserHandle = in.readTypedObject(UserHandle.CREATOR);
294         this.mAssociatedSmartspaceTargetId = in.readString();
295         this.mSliceUri = in.readTypedObject(Uri.CREATOR);
296         this.mWidget = in.readTypedObject(AppWidgetProviderInfo.CREATOR);
297         this.mTemplateData = in.readParcelable(/* loader= */null, BaseTemplateData.class);
298         this.mRemoteViews = in.readTypedObject(RemoteViews.CREATOR);
299     }
300 
SmartspaceTarget(String smartspaceTargetId, SmartspaceAction headerAction, SmartspaceAction baseAction, long creationTimeMillis, long expiryTimeMillis, float score, List<SmartspaceAction> actionChips, List<SmartspaceAction> iconGrid, int featureType, boolean sensitive, boolean shouldShowExpanded, String sourceNotificationKey, ComponentName componentName, UserHandle userHandle, String associatedSmartspaceTargetId, Uri sliceUri, AppWidgetProviderInfo widget, BaseTemplateData templateData, RemoteViews remoteViews)301     private SmartspaceTarget(String smartspaceTargetId,
302             SmartspaceAction headerAction, SmartspaceAction baseAction, long creationTimeMillis,
303             long expiryTimeMillis, float score,
304             List<SmartspaceAction> actionChips,
305             List<SmartspaceAction> iconGrid, int featureType, boolean sensitive,
306             boolean shouldShowExpanded, String sourceNotificationKey,
307             ComponentName componentName, UserHandle userHandle,
308             String associatedSmartspaceTargetId, Uri sliceUri,
309             AppWidgetProviderInfo widget, BaseTemplateData templateData, RemoteViews remoteViews) {
310         mSmartspaceTargetId = smartspaceTargetId;
311         mHeaderAction = headerAction;
312         mBaseAction = baseAction;
313         mCreationTimeMillis = creationTimeMillis;
314         mExpiryTimeMillis = expiryTimeMillis;
315         mScore = score;
316         mActionChips = actionChips;
317         mIconGrid = iconGrid;
318         mFeatureType = featureType;
319         mSensitive = sensitive;
320         mShouldShowExpanded = shouldShowExpanded;
321         mSourceNotificationKey = sourceNotificationKey;
322         mComponentName = componentName;
323         mUserHandle = userHandle;
324         mAssociatedSmartspaceTargetId = associatedSmartspaceTargetId;
325         mSliceUri = sliceUri;
326         mWidget = widget;
327         mTemplateData = templateData;
328         mRemoteViews = remoteViews;
329     }
330 
331     /**
332      * Returns the Id of the target.
333      */
334     @NonNull
getSmartspaceTargetId()335     public String getSmartspaceTargetId() {
336         return mSmartspaceTargetId;
337     }
338 
339     /**
340      * Returns the header action of the target.
341      */
342     @Nullable
getHeaderAction()343     public SmartspaceAction getHeaderAction() {
344         return mHeaderAction;
345     }
346 
347     /**
348      * Returns the base action of the target.
349      */
350     @Nullable
getBaseAction()351     public SmartspaceAction getBaseAction() {
352         return mBaseAction;
353     }
354 
355     /**
356      * Returns the creation time of the target.
357      */
358     @CurrentTimeMillisLong
getCreationTimeMillis()359     public long getCreationTimeMillis() {
360         return mCreationTimeMillis;
361     }
362 
363     /**
364      * Returns the expiry time of the target.
365      */
366     @CurrentTimeMillisLong
getExpiryTimeMillis()367     public long getExpiryTimeMillis() {
368         return mExpiryTimeMillis;
369     }
370 
371     /**
372      * Returns the score of the target.
373      */
getScore()374     public float getScore() {
375         return mScore;
376     }
377 
378     /**
379      * Return the action chips of the target.
380      */
381     @NonNull
getActionChips()382     public List<SmartspaceAction> getActionChips() {
383         return mActionChips;
384     }
385 
386     /**
387      * Return the icons of the target.
388      */
389     @NonNull
getIconGrid()390     public List<SmartspaceAction> getIconGrid() {
391         return mIconGrid;
392     }
393 
394     /**
395      * Returns the feature type of the target.
396      */
397     @FeatureType
getFeatureType()398     public int getFeatureType() {
399         return mFeatureType;
400     }
401 
402     /**
403      * Returns whether the target is sensitive or not.
404      */
isSensitive()405     public boolean isSensitive() {
406         return mSensitive;
407     }
408 
409     /**
410      * Returns whether the target should be shown in expanded state.
411      */
shouldShowExpanded()412     public boolean shouldShowExpanded() {
413         return mShouldShowExpanded;
414     }
415 
416     /**
417      * Returns the source notification key of the target.
418      */
419     @Nullable
getSourceNotificationKey()420     public String getSourceNotificationKey() {
421         return mSourceNotificationKey;
422     }
423 
424     /**
425      * Returns the component name of the target.
426      */
427     @NonNull
getComponentName()428     public ComponentName getComponentName() {
429         return mComponentName;
430     }
431 
432     /**
433      * Returns the user handle of the target.
434      */
435     @NonNull
getUserHandle()436     public UserHandle getUserHandle() {
437         return mUserHandle;
438     }
439 
440     /**
441      * Returns the id of a target associated with this instance.
442      */
443     @Nullable
getAssociatedSmartspaceTargetId()444     public String getAssociatedSmartspaceTargetId() {
445         return mAssociatedSmartspaceTargetId;
446     }
447 
448     /**
449      * Returns the slice uri, if the target is a slice.
450      */
451     @Nullable
getSliceUri()452     public Uri getSliceUri() {
453         return mSliceUri;
454     }
455 
456     /**
457      * Returns the AppWidgetProviderInfo, if the target is a widget.
458      */
459     @Nullable
getWidget()460     public AppWidgetProviderInfo getWidget() {
461         return mWidget;
462     }
463 
464     /**
465      * Returns the UI template data.
466      */
467     @Nullable
getTemplateData()468     public BaseTemplateData getTemplateData() {
469         return mTemplateData;
470     }
471 
472     /**
473      * Returns the {@link RemoteViews} to show over the target.
474      */
475     @FlaggedApi(Flags.FLAG_REMOTE_VIEWS)
476     @Nullable
getRemoteViews()477     public RemoteViews getRemoteViews() {
478         return mRemoteViews;
479     }
480 
481     /**
482      * @see Parcelable.Creator
483      */
484     @NonNull
485     public static final Creator<SmartspaceTarget> CREATOR = new Creator<SmartspaceTarget>() {
486         @Override
487         public SmartspaceTarget createFromParcel(Parcel source) {
488             return new SmartspaceTarget(source);
489         }
490 
491         @Override
492         public SmartspaceTarget[] newArray(int size) {
493             return new SmartspaceTarget[size];
494         }
495     };
496 
497     @Override
writeToParcel(@onNull Parcel dest, int flags)498     public void writeToParcel(@NonNull Parcel dest, int flags) {
499         dest.writeString(this.mSmartspaceTargetId);
500         dest.writeTypedObject(this.mHeaderAction, flags);
501         dest.writeTypedObject(this.mBaseAction, flags);
502         dest.writeLong(this.mCreationTimeMillis);
503         dest.writeLong(this.mExpiryTimeMillis);
504         dest.writeFloat(this.mScore);
505         dest.writeTypedList(this.mActionChips);
506         dest.writeTypedList(this.mIconGrid);
507         dest.writeInt(this.mFeatureType);
508         dest.writeBoolean(this.mSensitive);
509         dest.writeBoolean(this.mShouldShowExpanded);
510         dest.writeString(this.mSourceNotificationKey);
511         dest.writeTypedObject(this.mComponentName, flags);
512         dest.writeTypedObject(this.mUserHandle, flags);
513         dest.writeString(this.mAssociatedSmartspaceTargetId);
514         dest.writeTypedObject(this.mSliceUri, flags);
515         dest.writeTypedObject(this.mWidget, flags);
516         dest.writeParcelable(this.mTemplateData, flags);
517         dest.writeTypedObject(this.mRemoteViews, flags);
518     }
519 
520     @Override
describeContents()521     public int describeContents() {
522         return 0;
523     }
524 
525     @Override
toString()526     public String toString() {
527         return "SmartspaceTarget{"
528                 + "mSmartspaceTargetId='" + mSmartspaceTargetId + '\''
529                 + ", mHeaderAction=" + mHeaderAction
530                 + ", mBaseAction=" + mBaseAction
531                 + ", mCreationTimeMillis=" + mCreationTimeMillis
532                 + ", mExpiryTimeMillis=" + mExpiryTimeMillis
533                 + ", mScore=" + mScore
534                 + ", mActionChips=" + mActionChips
535                 + ", mIconGrid=" + mIconGrid
536                 + ", mFeatureType=" + mFeatureType
537                 + ", mSensitive=" + mSensitive
538                 + ", mShouldShowExpanded=" + mShouldShowExpanded
539                 + ", mSourceNotificationKey='" + mSourceNotificationKey + '\''
540                 + ", mComponentName=" + mComponentName
541                 + ", mUserHandle=" + mUserHandle
542                 + ", mAssociatedSmartspaceTargetId='" + mAssociatedSmartspaceTargetId + '\''
543                 + ", mSliceUri=" + mSliceUri
544                 + ", mWidget=" + mWidget
545                 + ", mTemplateData=" + mTemplateData
546                 + ", mRemoteViews=" + mRemoteViews
547                 + '}';
548     }
549 
550     @Override
equals(Object o)551     public boolean equals(Object o) {
552         if (this == o) return true;
553         if (o == null || getClass() != o.getClass()) return false;
554         SmartspaceTarget that = (SmartspaceTarget) o;
555         return mCreationTimeMillis == that.mCreationTimeMillis
556                 && mExpiryTimeMillis == that.mExpiryTimeMillis
557                 && Float.compare(that.mScore, mScore) == 0
558                 && mFeatureType == that.mFeatureType
559                 && mSensitive == that.mSensitive
560                 && mShouldShowExpanded == that.mShouldShowExpanded
561                 && mSmartspaceTargetId.equals(that.mSmartspaceTargetId)
562                 && Objects.equals(mHeaderAction, that.mHeaderAction)
563                 && Objects.equals(mBaseAction, that.mBaseAction)
564                 && Objects.equals(mActionChips, that.mActionChips)
565                 && Objects.equals(mIconGrid, that.mIconGrid)
566                 && Objects.equals(mSourceNotificationKey, that.mSourceNotificationKey)
567                 && mComponentName.equals(that.mComponentName)
568                 && mUserHandle.equals(that.mUserHandle)
569                 && Objects.equals(mAssociatedSmartspaceTargetId,
570                 that.mAssociatedSmartspaceTargetId)
571                 && Objects.equals(mSliceUri, that.mSliceUri)
572                 && Objects.equals(mWidget, that.mWidget)
573                 && Objects.equals(mTemplateData, that.mTemplateData)
574                 && Objects.equals(mRemoteViews, that.mRemoteViews);
575     }
576 
577     @Override
hashCode()578     public int hashCode() {
579         return Objects.hash(mSmartspaceTargetId, mHeaderAction, mBaseAction, mCreationTimeMillis,
580                 mExpiryTimeMillis, mScore, mActionChips, mIconGrid, mFeatureType, mSensitive,
581                 mShouldShowExpanded, mSourceNotificationKey, mComponentName, mUserHandle,
582                 mAssociatedSmartspaceTargetId, mSliceUri, mWidget, mTemplateData, mRemoteViews);
583     }
584 
585     /**
586      * A builder for {@link SmartspaceTarget} object.
587      *
588      * @hide
589      */
590     @SystemApi
591     public static final class Builder {
592         private final String mSmartspaceTargetId;
593         private final ComponentName mComponentName;
594         private final UserHandle mUserHandle;
595 
596         private SmartspaceAction mHeaderAction;
597         private SmartspaceAction mBaseAction;
598         private long mCreationTimeMillis;
599         private long mExpiryTimeMillis;
600         private float mScore;
601         private List<SmartspaceAction> mActionChips = new ArrayList<>();
602         private List<SmartspaceAction> mIconGrid = new ArrayList<>();
603         private int mFeatureType;
604         private boolean mSensitive;
605         private boolean mShouldShowExpanded;
606         private String mSourceNotificationKey;
607         private String mAssociatedSmartspaceTargetId;
608         private Uri mSliceUri;
609         private AppWidgetProviderInfo mWidget;
610         private BaseTemplateData mTemplateData;
611 
612         private RemoteViews mRemoteViews;
613 
614         /**
615          * A builder for {@link SmartspaceTarget}.
616          *
617          * @param smartspaceTargetId the id of this target
618          * @param componentName      the componentName of this target
619          * @param userHandle         the userHandle of this target
620          */
Builder(@onNull String smartspaceTargetId, @NonNull ComponentName componentName, @NonNull UserHandle userHandle)621         public Builder(@NonNull String smartspaceTargetId,
622                 @NonNull ComponentName componentName, @NonNull UserHandle userHandle) {
623             this.mSmartspaceTargetId = smartspaceTargetId;
624             this.mComponentName = componentName;
625             this.mUserHandle = userHandle;
626         }
627 
628         /**
629          * Sets the header action.
630          */
631         @NonNull
setHeaderAction(@onNull SmartspaceAction headerAction)632         public Builder setHeaderAction(@NonNull SmartspaceAction headerAction) {
633             this.mHeaderAction = headerAction;
634             return this;
635         }
636 
637         /**
638          * Sets the base action.
639          */
640         @NonNull
setBaseAction(@onNull SmartspaceAction baseAction)641         public Builder setBaseAction(@NonNull SmartspaceAction baseAction) {
642             this.mBaseAction = baseAction;
643             return this;
644         }
645 
646         /**
647          * Sets the creation time.
648          */
649         @NonNull
setCreationTimeMillis(@urrentTimeMillisLong long creationTimeMillis)650         public Builder setCreationTimeMillis(@CurrentTimeMillisLong long creationTimeMillis) {
651             this.mCreationTimeMillis = creationTimeMillis;
652             return this;
653         }
654 
655         /**
656          * Sets the expiration time.
657          */
658         @NonNull
setExpiryTimeMillis(@urrentTimeMillisLong long expiryTimeMillis)659         public Builder setExpiryTimeMillis(@CurrentTimeMillisLong long expiryTimeMillis) {
660             this.mExpiryTimeMillis = expiryTimeMillis;
661             return this;
662         }
663 
664         /**
665          * Sets the score.
666          */
667         @NonNull
setScore(float score)668         public Builder setScore(float score) {
669             this.mScore = score;
670             return this;
671         }
672 
673         /**
674          * Sets the action chips.
675          */
676         @NonNull
setActionChips(@onNull List<SmartspaceAction> actionChips)677         public Builder setActionChips(@NonNull List<SmartspaceAction> actionChips) {
678             this.mActionChips = actionChips;
679             return this;
680         }
681 
682         /**
683          * Sets the icon grid.
684          */
685         @NonNull
setIconGrid(@onNull List<SmartspaceAction> iconGrid)686         public Builder setIconGrid(@NonNull List<SmartspaceAction> iconGrid) {
687             this.mIconGrid = iconGrid;
688             return this;
689         }
690 
691         /**
692          * Sets the feature type.
693          */
694         @NonNull
setFeatureType(int featureType)695         public Builder setFeatureType(int featureType) {
696             this.mFeatureType = featureType;
697             return this;
698         }
699 
700         /**
701          * Sets whether the contents are sensitive.
702          */
703         @NonNull
setSensitive(boolean sensitive)704         public Builder setSensitive(boolean sensitive) {
705             this.mSensitive = sensitive;
706             return this;
707         }
708 
709         /**
710          * Sets whether to show the card as expanded.
711          */
712         @NonNull
setShouldShowExpanded(boolean shouldShowExpanded)713         public Builder setShouldShowExpanded(boolean shouldShowExpanded) {
714             this.mShouldShowExpanded = shouldShowExpanded;
715             return this;
716         }
717 
718         /**
719          * Sets the source notification key.
720          */
721         @NonNull
setSourceNotificationKey(@onNull String sourceNotificationKey)722         public Builder setSourceNotificationKey(@NonNull String sourceNotificationKey) {
723             this.mSourceNotificationKey = sourceNotificationKey;
724             return this;
725         }
726 
727         /**
728          * Sets the associated smartspace target id.
729          */
730         @NonNull
setAssociatedSmartspaceTargetId( @onNull String associatedSmartspaceTargetId)731         public Builder setAssociatedSmartspaceTargetId(
732                 @NonNull String associatedSmartspaceTargetId) {
733             this.mAssociatedSmartspaceTargetId = associatedSmartspaceTargetId;
734             return this;
735         }
736 
737         /**
738          * Sets the slice uri.
739          *
740          * <p><b>NOTE: </b> If {@link mWidget} is also set, {@link mSliceUri} should be ignored.
741          */
742         @NonNull
setSliceUri(@onNull Uri sliceUri)743         public Builder setSliceUri(@NonNull Uri sliceUri) {
744             this.mSliceUri = sliceUri;
745             return this;
746         }
747 
748         /**
749          * Sets the widget id.
750          *
751          * <p><b>NOTE: </b> If {@link mWidget} is set, all other @Nullable params should be
752          * ignored.
753          *
754          * @throws An {@link IllegalStateException} is thrown if {@link mRemoteViews} is set.
755          */
756         @NonNull
setWidget(@onNull AppWidgetProviderInfo widget)757         public Builder setWidget(@NonNull AppWidgetProviderInfo widget) {
758             if (mRemoteViews != null) {
759                 throw new IllegalStateException(
760                         "Widget providers and RemoteViews cannot be used at the same time.");
761             }
762             this.mWidget = widget;
763             return this;
764         }
765 
766         /**
767          * Sets the UI template data.
768          */
769         @NonNull
setTemplateData( @ullable BaseTemplateData templateData)770         public Builder setTemplateData(
771                 @Nullable BaseTemplateData templateData) {
772             mTemplateData = templateData;
773             return this;
774         }
775 
776         /**
777          * Sets the {@link RemoteViews}.
778          *
779          * <p><b>NOTE: </b> If {@link RemoteViews} is set, all other @Nullable params should be
780          * ignored.
781          *
782          * @throws An {@link IllegalStateException} is thrown if {@link mWidget} is set.
783          */
784         @FlaggedApi(Flags.FLAG_REMOTE_VIEWS)
785         @NonNull
setRemoteViews(@onNull RemoteViews remoteViews)786         public Builder setRemoteViews(@NonNull RemoteViews remoteViews) {
787             if (mWidget != null) {
788                 throw new IllegalStateException(
789                         "Widget providers and RemoteViews cannot be used at the same time.");
790             }
791             mRemoteViews = remoteViews;
792             return this;
793         }
794 
795         /**
796          * Builds a new {@link SmartspaceTarget}.
797          *
798          * @throws IllegalStateException when non null fields are set as null.
799          */
800         @NonNull
build()801         public SmartspaceTarget build() {
802             if (mSmartspaceTargetId == null
803                     || mComponentName == null
804                     || mUserHandle == null) {
805                 throw new IllegalStateException("Please assign a value to all @NonNull args.");
806             }
807             return new SmartspaceTarget(mSmartspaceTargetId,
808                     mHeaderAction, mBaseAction, mCreationTimeMillis, mExpiryTimeMillis, mScore,
809                     mActionChips, mIconGrid, mFeatureType, mSensitive, mShouldShowExpanded,
810                     mSourceNotificationKey, mComponentName, mUserHandle,
811                     mAssociatedSmartspaceTargetId, mSliceUri, mWidget, mTemplateData, mRemoteViews);
812         }
813     }
814 }
815