1 /*
2  * Copyright (C) 2019 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 com.android.tv.twopanelsettings.slices.builders;
18 
19 import static com.android.tv.twopanelsettings.slices.SlicesConstants.BUTTONSTYLE;
20 import static com.android.tv.twopanelsettings.slices.SlicesConstants.CHECKMARK;
21 import static com.android.tv.twopanelsettings.slices.SlicesConstants.RADIO;
22 import static com.android.tv.twopanelsettings.slices.SlicesConstants.SWITCH;
23 
24 import android.app.PendingIntent;
25 import android.content.Context;
26 import android.net.Uri;
27 import android.view.View;
28 
29 import androidx.annotation.IntDef;
30 import androidx.annotation.NonNull;
31 import androidx.annotation.Nullable;
32 import androidx.annotation.RestrictTo;
33 import androidx.core.graphics.drawable.IconCompat;
34 import androidx.core.util.Pair;
35 import androidx.slice.Slice;
36 import androidx.slice.SliceSpecs;
37 import androidx.slice.builders.ListBuilder;
38 import androidx.slice.builders.SliceAction;
39 import androidx.slice.core.SliceHints;
40 
41 import java.lang.annotation.Retention;
42 import java.lang.annotation.RetentionPolicy;
43 import java.time.Duration;
44 import java.util.ArrayList;
45 import java.util.List;
46 
47 // TODO: Remove unused code and add test.
48 /**
49  * Builder for constructing slices composed of rows of TvSettings style preferences.
50  */
51 public class PreferenceSliceBuilder extends TemplateSliceBuilder {
52 
53     private PreferenceSliceBuilderImpl mImpl;
54 
55     /**
56      * Constant representing infinity.
57      */
58     public static final long INFINITY = SliceHints.INFINITY;
59 
60     /**
61      * @hide
62      */
63     @RestrictTo(RestrictTo.Scope.LIBRARY)
64     @IntDef({
65         View.LAYOUT_DIRECTION_RTL, View.LAYOUT_DIRECTION_LTR, View.LAYOUT_DIRECTION_INHERIT,
66         View.LAYOUT_DIRECTION_LOCALE
67     })
68     @Retention(RetentionPolicy.SOURCE)
69     public @interface LayoutDirection {
70 
71     }
72 
73     /**
74      * Create a builder which will construct a slice made up of rows of content.
75      *
76      * @param uri Uri to tag for this slice.
77      * @hide
78      */
PreferenceSliceBuilder(@onNull Context context, @NonNull Uri uri)79     public PreferenceSliceBuilder(@NonNull Context context, @NonNull Uri uri) {
80         super(context, uri);
81     }
82 
83     /**
84      * Create a ListBuilder for constructing slice content.
85      * <p>
86      * A slice requires an associated time-to-live, i.e. how long the data contained in the slice
87      * can remain fresh. If your slice has content that is not time sensitive, set a TTL of {@link
88      * #INFINITY}.
89      *
90      * @param uri Uri to tag for this slice.
91      * @param ttl the length in milliseconds that the content in this slice can live for.
92      */
PreferenceSliceBuilder(@onNull Context context, @NonNull Uri uri, long ttl)93     public PreferenceSliceBuilder(@NonNull Context context, @NonNull Uri uri, long ttl) {
94         super(context, uri);
95         mImpl.setTtl(ttl);
96     }
97 
98     /**
99      * Create a ListBuilder for constructing slice content.
100      * <p>
101      * A slice requires an associated time-to-live, i.e. how long the data contained in the slice
102      * can remain fresh. If your slice has content that is not time sensitive, set {@link Duration}
103      * to null and the TTL will be {@link #INFINITY}.
104      *
105      * @param uri Uri to tag for this slice.
106      * @param ttl the {@link Duration} that the content in this slice can live for.
107      */
PreferenceSliceBuilder(@onNull Context context, @NonNull Uri uri, @Nullable Duration ttl)108     public PreferenceSliceBuilder(@NonNull Context context, @NonNull Uri uri,
109             @Nullable Duration ttl) {
110         super(context, uri);
111         mImpl.setTtl(ttl);
112     }
113 
114     @Override
selectImpl(Uri uri)115     protected TemplateBuilderImpl selectImpl(Uri uri) {
116         return new PreferenceSliceBuilderImpl(getBuilder(), SliceSpecs.LIST, getClock());
117     }
118 
119     /**
120      * Construct the slice defined by this PreferenceSliceBuilder
121      */
122     @NonNull
123     @Override
build()124     public Slice build() {
125         return mImpl.build();
126     }
127 
128     @Override
setImpl(TemplateBuilderImpl impl)129     void setImpl(TemplateBuilderImpl impl) {
130         mImpl = (PreferenceSliceBuilderImpl) impl;
131     }
132 
133     /**
134      * Add a preference builder. If the row is expected to be actionable, it is recommended to
135      * invoke setActionId() for the RowBuilder to help with logging.
136      */
addPreference(RowBuilder builder)137     public PreferenceSliceBuilder addPreference(RowBuilder builder) {
138         mImpl.addPreference(builder);
139         return this;
140     }
141 
142     /**
143      * Add a preferenceCategory builder.
144      */
addPreferenceCategory(RowBuilder builder)145     public PreferenceSliceBuilder addPreferenceCategory(RowBuilder builder) {
146         mImpl.addPreferenceCategory(builder);
147         return this;
148     }
149 
150     /**
151      * Set a custom screen title for slice. It is recommended to invoke setPageId() for the
152      * RowBuilder in addition to setTitle(), to help with logging.
153      */
addScreenTitle(RowBuilder builder)154     public PreferenceSliceBuilder addScreenTitle(RowBuilder builder) {
155         mImpl.addScreenTitle(builder);
156         return this;
157     }
158 
159     /**
160      * Set the focused preference for slice.
161      * @param key key of the focused preference.
162      */
setFocusedPreference(CharSequence key)163     public PreferenceSliceBuilder setFocusedPreference(CharSequence key) {
164         mImpl.setFocusedPreference(key);
165         return this;
166     }
167 
168     /** Add a preference which can be embedded in other settings items. **/
setEmbeddedPreference(RowBuilder builder)169     public PreferenceSliceBuilder setEmbeddedPreference(RowBuilder builder) {
170         mImpl.setEmbeddedPreference(builder);
171         return this;
172     }
173 
174     /** Indicates that the slice is not ready yet **/
setNotReady()175     public PreferenceSliceBuilder setNotReady() {
176         mImpl.setNotReady();
177         return this;
178     }
179 
180     public static class RowBuilder {
181 
182         private final Uri mUri;
183         private boolean mHasEndActionOrToggle;
184         private boolean mHasEndImage;
185         private boolean mHasDefaultToggle;
186         private boolean mTitleItemLoading;
187         private IconCompat mTitleIcon;
188         private SliceAction mTitleAction;
189         private SliceAction mPrimaryAction;
190         private SliceAction mFollowupAction;
191         private int mActionId;
192         private int mPageId;
193         private CharSequence mTitle;
194         private boolean mTitleLoading;
195         private CharSequence mSubtitle;
196         private boolean mSubtitleLoading;
197         private CharSequence mContentDescription;
198         private CharSequence mInfoText;
199         private IconCompat mInfoImage;
200         private int mLayoutDirection = -1;
201         private List<Object> mEndItems = new ArrayList<>();
202         private List<Integer> mEndTypes = new ArrayList<>();
203         private List<Boolean> mEndLoads = new ArrayList<>();
204         private List<Pair<String, String>> mInfoItems = new ArrayList<>();
205         private boolean mTitleActionLoading;
206         private CharSequence mTargetSliceUri;
207         private CharSequence mKey;
208         private boolean mIconNeedsToBeProcessed;
209         private @BUTTONSTYLE int mButtonStyle;
210         private CharSequence mRadioGroup;
211         private boolean mEnabled;
212         private boolean mSelectable;
213 
214         public static final int TYPE_ICON = 1;
215         public static final int TYPE_ACTION = 2;
216 
217         /**
218          * Builder to construct a row.
219          */
RowBuilder()220         public RowBuilder() {
221             mEnabled = true;
222             mSelectable = true;
223             mUri = null;
224         }
225 
226         /**
227          * Builder to construct a normal row.
228          *
229          * @param uri Uri to tag for this slice.
230          */
RowBuilder(Uri uri)231         public RowBuilder(Uri uri) {
232             mEnabled = true;
233             mSelectable = true;
234             mUri = uri;
235         }
236 
237         /**
238          * Builder to construct a row.
239          *
240          * @param parent The builder constructing the parent slice.
241          */
RowBuilder(@onNull ListBuilder parent)242         public RowBuilder(@NonNull ListBuilder parent) {
243             this();
244         }
245 
246         /**
247          * Builder to construct a row.
248          *
249          * @param uri Uri to tag for this slice.
250          */
RowBuilder(@onNull ListBuilder parent, @NonNull Uri uri)251         public RowBuilder(@NonNull ListBuilder parent, @NonNull Uri uri) {
252             this(uri);
253         }
254 
255         /**
256          * Builder to construct a normal row.
257          *
258          * @param uri Uri to tag for this slice.
259          */
RowBuilder(@onNull Context context, @NonNull Uri uri)260         public RowBuilder(@NonNull Context context, @NonNull Uri uri) {
261             this(uri);
262         }
263 
264         /**
265          * Sets the title item to be the provided icon. There can only be one title item, this will
266          * replace any other title items that may have been set.
267          *
268          * @param icon the image to display.
269          */
setTitleItem(@onNull IconCompat icon)270         private RowBuilder setTitleItem(@NonNull IconCompat icon) {
271             return setTitleItem(icon, false /* isLoading */);
272         }
273 
274         /**
275          * Sets the title item to be the provided icon. There can only be one title item, this will
276          * replace any other title items that may have been set.
277          * <p>
278          * When set to true, the parameter {@code isLoading} indicates that the app is doing work to
279          * load this content in the background, in this case the template displays a placeholder
280          * until updated.
281          *
282          * @param icon the image to display.
283          * @param isLoading whether this content is being loaded in the background.
284          */
285         @NonNull
setTitleItem(@ullable IconCompat icon, boolean isLoading)286         private RowBuilder setTitleItem(@Nullable IconCompat icon, boolean isLoading) {
287             mTitleAction = null;
288             mTitleIcon = icon;
289             mTitleItemLoading = isLoading;
290             return this;
291         }
292 
293         /**
294          * Sets the title item to be a tappable icon. There can only be one title item, this will
295          * replace any other title items that may have been set.
296          */
297         @NonNull
setTitleItem(@onNull SliceAction action)298         private RowBuilder setTitleItem(@NonNull SliceAction action) {
299             return setTitleItem(action, false /* isLoading */);
300         }
301 
302         /**
303          * Sets the title item to be a tappable icon. There can only be one title item, this will
304          * replace any other title items that may have been set.
305          * <p>
306          * Use this method to specify content that will appear in the template once it's been
307          * loaded.
308          * </p>
309          *
310          * @param isLoading indicates whether the app is doing work to load the added content in the
311          * background or not.
312          */
313         @NonNull
setTitleItem(@onNull SliceAction action, boolean isLoading)314         private RowBuilder setTitleItem(@NonNull SliceAction action, boolean isLoading) {
315             mTitleAction = action;
316             mTitleIcon = null;
317             mTitleActionLoading = isLoading;
318             return this;
319         }
320 
321         /**
322          * Sets the icon for the preference builder.
323          */
324         @NonNull
setIcon(@onNull IconCompat icon)325         public RowBuilder setIcon(@NonNull IconCompat icon) {
326             return setTitleItem(icon);
327         }
328 
329         /**
330          * Sets the information image for the preference builder.
331          * The image would be displayed at the top of preview screen.
332          */
333         @NonNull
setInfoImage(@onNull IconCompat icon)334         public RowBuilder setInfoImage(@NonNull IconCompat icon) {
335             mInfoImage = icon;
336             return this;
337         }
338 
339         /**
340          * Sets the information text for the preference builder.
341          * The image would be displayed at the top of preview screen.
342          */
343         @NonNull
setInfoText(CharSequence text)344         public RowBuilder setInfoText(CharSequence text) {
345             mInfoText = text;
346             return this;
347         }
348 
349         /**
350          * The action specified here will be sent when the whole row is clicked.
351          * <p>
352          * If this is the first row in a {@link ListBuilder} this action will also be used to define
353          * the {@link androidx.slice.widget.SliceView#MODE_SHORTCUT} representation of the slice.
354          */
355         @NonNull
setPrimaryAction(@onNull SliceAction action)356         private RowBuilder setPrimaryAction(@NonNull SliceAction action) {
357             mPrimaryAction = action;
358             return this;
359         }
360 
361         /**
362          * Set a pendingIntent for the preference builder.
363          * @param pendingIntent pendingIntent
364          * @return builder
365          */
366         @NonNull
setPendingIntent(@onNull PendingIntent pendingIntent)367         public RowBuilder setPendingIntent(@NonNull PendingIntent pendingIntent) {
368             return setPrimaryAction(new SliceAction(pendingIntent, "", false));
369         }
370 
371         /**
372          * Set a followup pendingIntent for the preference builder. After the initial pendingIntent
373          * is launched and result is retrieved by TvSettings, TvSettings will pack the result into
374          * the followup PendingIntent and launch it.
375          * @param pendingIntent followup pendingIntent
376          * @return builder
377          */
378         @NonNull
setFollowupPendingIntent(@onNull PendingIntent pendingIntent)379         public RowBuilder setFollowupPendingIntent(@NonNull PendingIntent pendingIntent) {
380             mFollowupAction = new SliceAction(pendingIntent, "", false);
381             return this;
382         }
383 
384         /**
385          * Set the action ID for the row builder. If this is invoked for building an actionable row,
386          * it will be digested as actionId for logging purpose when the action is triggered.
387          *
388          * @param actionId pre-defined ID of an action
389          */
390         @NonNull
setActionId(int actionId)391         public RowBuilder setActionId(int actionId) {
392             mActionId = actionId;
393             return this;
394         }
395 
396         /**
397          * Set the page ID for the row builder. If this is invoked for building the screen title
398          * row, it will be digested as pageId for logging purpose when the SliceFragment is focused.
399          *
400          * @param pageId pre-defined ID of a page
401          */
402         @NonNull
setPageId(int pageId)403         public RowBuilder setPageId(int pageId) {
404             mPageId = pageId;
405             return this;
406         }
407 
408       /**
409          * Sets the title for the row builder. A title should fit on a single line and is ellipsized
410          * if too long.
411          */
412         @NonNull
setTitle(@onNull CharSequence title)413         public RowBuilder setTitle(@NonNull CharSequence title) {
414             return setTitle(title, false);
415         }
416 
417         /**
418          * Sets the title for the row builder. A title should fit on a single line and is ellipsized
419          * if too long.
420          * <p>
421          * Use this method to specify content that will appear in the template once it's been
422          * loaded.
423          * </p>
424          *
425          * @param isLoading indicates whether the app is doing work to load the added content in the
426          * background or not.
427          */
428         @NonNull
setTitle(@ullable CharSequence title, boolean isLoading)429         public RowBuilder setTitle(@Nullable CharSequence title, boolean isLoading) {
430             mTitle = title;
431             mTitleLoading = isLoading;
432             return this;
433         }
434 
435         /**
436          * Sets the subtitle for the row builder. A subtitle should fit on a single line and is
437          * ellipsized if too long.
438          */
439         @NonNull
setSubtitle(@onNull CharSequence subtitle)440         public RowBuilder setSubtitle(@NonNull CharSequence subtitle) {
441             return setSubtitle(subtitle, false /* isLoading */);
442         }
443 
444         /**
445          * Sets the subtitle for the row builder. A subtitle should fit on a single line and is
446          * ellipsized if too long.
447          * <p>
448          * Use this method to specify content that will appear in the template once it's been
449          * loaded.
450          * </p>
451          *
452          * @param isLoading indicates whether the app is doing work to load the added content in the
453          * background or not.
454          */
455         @NonNull
setSubtitle(@ullable CharSequence subtitle, boolean isLoading)456         public RowBuilder setSubtitle(@Nullable CharSequence subtitle, boolean isLoading) {
457             mSubtitle = subtitle;
458             mSubtitleLoading = isLoading;
459             return this;
460         }
461 
462         /**
463          * Adds an icon to the end items of the row builder.
464          *
465          * @param icon the image to display.
466          */
467         @NonNull
addEndItem(@onNull IconCompat icon)468         private RowBuilder addEndItem(@NonNull IconCompat icon) {
469             return addEndItem(icon, false /* isLoading */);
470         }
471 
472         /**
473          * Adds an icon to the end items of the row builder.
474          * <p>
475          * When set to true, the parameter {@code isLoading} indicates that the app is doing work to
476          * load this content in the background, in this case the template displays a placeholder
477          * until updated.
478          *
479          * @param icon the image to display.
480          * @param isLoading whether this content is being loaded in the background.
481          */
482         @NonNull
addEndItem(@ullable IconCompat icon, boolean isLoading)483         private RowBuilder addEndItem(@Nullable IconCompat icon, boolean isLoading) {
484             if (mHasEndActionOrToggle) {
485                 throw new IllegalArgumentException("Trying to add an icon to end items when an"
486                     + "action has already been added. End items cannot have a mixture of "
487                     + "actions and icons.");
488             }
489             mEndItems.add(new Pair<>(icon, 0));
490             mEndTypes.add(TYPE_ICON);
491             mEndLoads.add(isLoading);
492             mHasEndImage = true;
493             return this;
494         }
495 
496         /**
497          * Adds an action to the end items of the row builder. A mixture of icons and actions is not
498          * permitted. If an icon has already been added, this will throw {@link
499          * IllegalArgumentException}.
500          */
501         @NonNull
addEndItem(@onNull SliceAction action)502         private RowBuilder addEndItem(@NonNull SliceAction action) {
503             return addEndItem(action, false /* isLoading */);
504         }
505 
506 
507         /**
508          * Add an item to the RowBuilder. Each item would contain title and summary.
509          */
addInfoItem(String title, String summary)510         public RowBuilder addInfoItem(String title, String summary) {
511             mInfoItems.add(new Pair<>(title, summary));
512             return this;
513         }
514 
515         /**
516          * Add a radio button to the RowBuilder.
517          * @param pendingIntent pendingIntent to launch when radio is clicked.
518          * @param isChecked Initial state of the radio button
519          */
addRadioButton( PendingIntent pendingIntent, boolean isChecked)520         public RowBuilder addRadioButton(
521                 PendingIntent pendingIntent, boolean isChecked) {
522             return addButton(pendingIntent, isChecked, RADIO);
523         }
524 
525         /**
526          * Add a radio button to the RowBuilder.
527          * @param pendingIntent pendingIntent to launch when radio is clicked.
528          * @param isChecked Initial state of the radio button
529          * @param radioGroup group of the radio
530          */
addRadioButton( PendingIntent pendingIntent, boolean isChecked, CharSequence radioGroup)531         public RowBuilder addRadioButton(
532                 PendingIntent pendingIntent, boolean isChecked, CharSequence radioGroup) {
533             return addButton(pendingIntent, isChecked, RADIO).setRadioGroup(radioGroup);
534         }
535 
536         /**
537          * Add a checkmark to the RowBuilder.
538          * @param pendingIntent pendingIntent to launch when checkmark is clicked.
539          * @param isChecked Initial state of the check mark.
540          */
addCheckMark( PendingIntent pendingIntent, boolean isChecked)541         public RowBuilder addCheckMark(
542                 PendingIntent pendingIntent, boolean isChecked) {
543             return addButton(pendingIntent, isChecked, CHECKMARK);
544         }
545 
546         /**
547          * Add a switch to the RowBuilder.
548          * @param pendingIntent pendingIntent to launch when switch is clicked.
549          * @param isChecked Initial state of the switch.
550          */
addSwitch( PendingIntent pendingIntent, boolean isChecked)551         public RowBuilder addSwitch(
552                 PendingIntent pendingIntent, boolean isChecked) {
553             return addButton(pendingIntent, isChecked, SWITCH);
554         }
555 
addButton( PendingIntent pendingIntent, boolean isChecked, @BUTTONSTYLE int style)556         private RowBuilder addButton(
557                 PendingIntent pendingIntent, boolean isChecked, @BUTTONSTYLE int style) {
558             SliceAction switchAction = new SliceAction(pendingIntent, "", isChecked);
559             mButtonStyle = style;
560             return addEndItem(switchAction);
561         }
562 
563         /**
564          * Add a switch for the preference.
565          * @param pendingIntent pendingIntent
566          * @param actionTitle title for the switch, also used for contentDescription.
567          * @param isChecked the state of the switch
568          * @return
569          */
570         @NonNull
addSwitch( PendingIntent pendingIntent, @NonNull CharSequence actionTitle, boolean isChecked)571         public PreferenceSliceBuilder.RowBuilder addSwitch(
572                 PendingIntent pendingIntent, @NonNull CharSequence actionTitle, boolean isChecked) {
573             SliceAction switchAction = new SliceAction(pendingIntent, actionTitle, isChecked);
574             mButtonStyle = SWITCH;
575             return addEndItem(switchAction);
576         }
577 
578         /**
579          * Adds an action to the end items of the row builder. A mixture of icons and actions is not
580          * permitted. If an icon has already been added, this will throw {@link
581          * IllegalArgumentException}.
582          * <p>
583          * Use this method to specify content that will appear in the template once it's been
584          * loaded.
585          * </p>
586          *
587          * @param isLoading indicates whether the app is doing work to load the added content in the
588          * background or not.
589          */
590         @NonNull
addEndItem(@onNull SliceAction action, boolean isLoading)591         private RowBuilder addEndItem(@NonNull SliceAction action, boolean isLoading) {
592             if (mHasEndImage) {
593                 throw new IllegalArgumentException("Trying to add an action to end items when an"
594                     + "icon has already been added. End items cannot have a mixture of "
595                     + "actions and icons.");
596             }
597             if (mHasDefaultToggle) {
598                 throw new IllegalStateException("Only one non-custom toggle can be added "
599                     + "in a single row. If you would like to include multiple toggles "
600                     + "in a row, set a custom icon for each toggle.");
601             }
602             mEndItems.add(action);
603             mEndTypes.add(TYPE_ACTION);
604             mEndLoads.add(isLoading);
605             mHasDefaultToggle = action.getImpl().isDefaultToggle();
606             mHasEndActionOrToggle = true;
607             return this;
608         }
609 
610         /**
611          * Sets the content description for the row.
612          */
613         @NonNull
setContentDescription(@onNull CharSequence description)614         public RowBuilder setContentDescription(@NonNull CharSequence description) {
615             mContentDescription = description;
616             return this;
617         }
618 
619         /**
620          * Set the target slice uri for the builder.
621          * @param targetSliceUri indicates the target slice uri when the preference is focused.
622          * @return builder
623          */
setTargetSliceUri(@onNull CharSequence targetSliceUri)624         public RowBuilder setTargetSliceUri(@NonNull CharSequence targetSliceUri) {
625             mTargetSliceUri = targetSliceUri;
626             return this;
627         }
628 
629         /**
630          * Set the key for the builder.
631          * @param key indicates the key for the preference.
632          * @return builder
633          */
setKey(@onNull CharSequence key)634         public RowBuilder setKey(@NonNull CharSequence key) {
635             mKey = key;
636             return this;
637         }
638 
639         /**
640          * Sets the desired layout direction for the content in this row.
641          *
642          * @param layoutDirection the layout direction to set.
643          */
644         @NonNull
setLayoutDirection(@ayoutDirection int layoutDirection)645         public RowBuilder setLayoutDirection(@LayoutDirection int layoutDirection) {
646             mLayoutDirection = layoutDirection;
647             return this;
648         }
649 
650         /**
651          * Set whether the toggle use a checkmark style. Otherwise, a switch style is used.
652          * @param isCheckMark use checkmark.
653          * @deprecated use {@link PreferenceSliceBuilder.RowBuilder#setButtonStyle(int)}
654          */
655         @Deprecated
656         @NonNull
setCheckmark(boolean isCheckMark)657         public RowBuilder setCheckmark(boolean isCheckMark) {
658             if (isCheckMark) {
659                 mButtonStyle = CHECKMARK;
660             } else {
661                 mButtonStyle = SWITCH;
662             }
663             return this;
664         }
665 
666         /**
667          * Set the button style.
668          * @param buttonStyle
669          */
setButtonStyle(@UTTONSTYLE int buttonStyle)670         public RowBuilder setButtonStyle(@BUTTONSTYLE int buttonStyle) {
671             mButtonStyle = buttonStyle;
672             return this;
673         }
674 
675         /**
676          * Set whether the icon needs to be processed by TvSettings.
677          * @param needed if true, TvSettings will add a round border around the given icon
678          */
679         @NonNull
setIconNeedsToBeProcessed(boolean needed)680         public RowBuilder setIconNeedsToBeProcessed(boolean needed) {
681             mIconNeedsToBeProcessed = needed;
682             return this;
683         }
684 
685         /**
686          * Set radio group for radio
687          */
688         @NonNull
setRadioGroup(CharSequence radioGroup)689         public RowBuilder setRadioGroup(CharSequence radioGroup) {
690             mRadioGroup = radioGroup;
691             return this;
692         }
693 
694         /**
695          * Set whether this item is enabled.
696          */
697         @NonNull
setEnabled(boolean enabled)698         public RowBuilder setEnabled(boolean enabled) {
699             mEnabled = enabled;
700             return this;
701         }
702 
703         /**
704          * Set whether this item is selectable.
705          * @param selectable
706          */
707         @NonNull
setSelectable(boolean selectable)708         public RowBuilder setSelectable(boolean selectable) {
709             mSelectable = selectable;
710             return this;
711         }
712 
713         /**
714          *
715          */
iconNeedsToBeProcessed()716         public boolean iconNeedsToBeProcessed() {
717             return mIconNeedsToBeProcessed;
718         }
719 
720         /**
721          *
722          */
getButtonStyle()723         public int getButtonStyle() {
724             return mButtonStyle;
725         }
726 
727         /**
728          * Get the target slice uri.
729          */
getTargetSliceUri()730         public CharSequence getTargetSliceUri() {
731             return mTargetSliceUri;
732         }
733 
734         /** Get the key for the builder */
getKey()735         public CharSequence getKey() {
736             return mKey;
737         }
738 
getUri()739         public Uri getUri() {
740             return mUri;
741         }
742 
hasEndActionOrToggle()743         public boolean hasEndActionOrToggle() {
744             return mHasEndActionOrToggle;
745         }
746 
hasEndImage()747         public boolean hasEndImage() {
748             return mHasEndImage;
749         }
750 
hasDefaultToggle()751         public boolean hasDefaultToggle() {
752             return mHasDefaultToggle;
753         }
754 
getRadioGroup()755         public CharSequence getRadioGroup() {
756             return mRadioGroup;
757         }
758 
isEnabled()759         public boolean isEnabled() {
760             return mEnabled;
761         }
762 
isSelectable()763         public boolean isSelectable() {
764             return mSelectable;
765         }
766 
isTitleItemLoading()767         public boolean isTitleItemLoading() {
768             return mTitleItemLoading;
769         }
770 
getTitleIcon()771         public IconCompat getTitleIcon() {
772             return mTitleIcon;
773         }
774 
getTitleAction()775         public SliceAction getTitleAction() {
776             return mTitleAction;
777         }
778 
getPrimaryAction()779         public SliceAction getPrimaryAction() {
780             return mPrimaryAction;
781         }
782 
getFollowupAction()783         public SliceAction getFollowupAction() {
784             return mFollowupAction;
785         }
786 
getActionId()787         public int getActionId() {
788             return mActionId;
789         }
790 
getPageId()791         public int getPageId() {
792             return mPageId;
793         }
794 
getTitle()795         public CharSequence getTitle() {
796             return mTitle;
797         }
798 
isTitleLoading()799         public boolean isTitleLoading() {
800             return mTitleLoading;
801         }
802 
getSubtitle()803         public CharSequence getSubtitle() {
804             return mSubtitle;
805         }
806 
isSubtitleLoading()807         public boolean isSubtitleLoading() {
808             return mSubtitleLoading;
809         }
810 
getContentDescription()811         public CharSequence getContentDescription() {
812             return mContentDescription;
813         }
814 
getLayoutDirection()815         public int getLayoutDirection() {
816             return mLayoutDirection;
817         }
818 
getInfoText()819         public CharSequence getInfoText() {
820             return mInfoText;
821         }
822 
getInfoImage()823         public IconCompat getInfoImage() {
824             return mInfoImage;
825         }
826 
getEndItems()827         public List<Object> getEndItems() {
828             return mEndItems;
829         }
830 
getInfoItems()831         public List<Pair<String, String>> getInfoItems() {
832             return mInfoItems;
833         }
834 
getEndTypes()835         public List<Integer> getEndTypes() {
836             return mEndTypes;
837         }
838 
getEndLoads()839         public List<Boolean> getEndLoads() {
840             return mEndLoads;
841         }
842 
isTitleActionLoading()843         public boolean isTitleActionLoading() {
844             return mTitleActionLoading;
845         }
846     }
847 }
848