• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 
17 package com.android.tv.twopanelsettings.slices.compat.builders;
18 
19 import android.app.PendingIntent;
20 import android.os.Parcelable;
21 import androidx.annotation.NonNull;
22 import androidx.annotation.Nullable;
23 import androidx.collection.ArraySet;
24 import androidx.core.util.Pair;
25 import androidx.remotecallback.RemoteCallback;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.Set;
29 
30 /**
31  * Builder to construct a selection which can be added to a {@link ListBuilder}.
32  *
33  * <p>A selection presents a list of options to the user and allows the user to select exactly one
34  * option.
35  *
36  * <p>Slice framework has been deprecated, it will not receive any updates moving forward. If you
37  * are looking for a framework that handles communication across apps, consider using {@link
38  * android.app.appsearch.AppSearchManager}.
39  */
40 // @Deprecated // Supported for TV
41 public class SelectionBuilder {
42   private final List<Pair<String, CharSequence>> mOptions;
43   private final Set<String> mOptionKeys;
44   private String mSelectedOption;
45   private SliceAction mPrimaryAction;
46   private Parcelable mInputAction;
47 
48   private CharSequence mTitle;
49   private CharSequence mSubtitle;
50   private CharSequence mContentDescription;
51   private int mLayoutDirection;
52 
53   /** Creates a SelectionBuilder with no options. */
SelectionBuilder()54   public SelectionBuilder() {
55     mOptions = new ArrayList<>();
56     mOptionKeys = new ArraySet<>();
57     mSelectedOption = null;
58     mLayoutDirection = -1;
59   }
60 
61   /**
62    * Adds an option to this SelectionBuilder.
63    *
64    * <p>The new option will be appended to the list of options.
65    *
66    * @param optionKey the key that will be returned if the user selects this option
67    * @param optionText the text that will be displayed to the user for this option
68    * @return this SelectionBuilder
69    */
addOption(String optionKey, CharSequence optionText)70   public SelectionBuilder addOption(String optionKey, CharSequence optionText) {
71     if (mOptionKeys.contains(optionKey)) {
72       throw new IllegalArgumentException("optionKey " + optionKey + " is a duplicate");
73     }
74 
75     mOptions.add(new Pair<>(optionKey, optionText));
76     mOptionKeys.add(optionKey);
77     return this;
78   }
79 
80   /**
81    * Sets the primary action for the selection slice.
82    *
83    * <p>The action specified here will be sent when the whole slice is clicked, or when the app
84    * presenting the slice is not capable of rendering a selection interface.
85    *
86    * @param primaryAction the action to trigger when the user clicks the whole slice
87    * @return this SelectionBuilder
88    */
setPrimaryAction(@onNull SliceAction primaryAction)89   public SelectionBuilder setPrimaryAction(@NonNull SliceAction primaryAction) {
90     mPrimaryAction = primaryAction;
91     return this;
92   }
93 
94   /**
95    * Sets the {@link PendingIntent} to send when the selection is made or changed.
96    *
97    * <p>The intent will include an extra with the key {@link
98    * com.android.tv.twopanelsettings.slices.compat.Slice#EXTRA_SELECTION} and a {@link String} value
99    * containing the key of the key of the selected option.
100    *
101    * @param inputAction the intent to send when the user makes or changes the selection
102    * @return this SelectionBuilder
103    */
setInputAction(@onNull PendingIntent inputAction)104   public SelectionBuilder setInputAction(@NonNull PendingIntent inputAction) {
105     mInputAction = inputAction;
106     return this;
107   }
108 
109   /**
110    * Sets the {@link RemoteCallback} to send when the selection is made or changed.
111    *
112    * <p>The intent will include an extra with the key {@link
113    * com.android.tv.twopanelsettings.slices.compat.Slice#EXTRA_SELECTION} and a {@link String} value
114    * containing the key of the key of the selected option.
115    *
116    * @param inputAction the intent to send when the user makes or changes the selection
117    * @return this SelectionBuilder
118    */
setInputAction(@onNull RemoteCallback inputAction)119   public SelectionBuilder setInputAction(@NonNull RemoteCallback inputAction) {
120     mInputAction = inputAction.toPendingIntent();
121     return this;
122   }
123 
124   /**
125    * Sets which option is selected by default.
126    *
127    * @param selectedOption the key of the selected option
128    * @return this SelectionBuilder
129    */
setSelectedOption(String selectedOption)130   public SelectionBuilder setSelectedOption(String selectedOption) {
131     mSelectedOption = selectedOption;
132     return this;
133   }
134 
135   /**
136    * Sets the title.
137    *
138    * @param title the title
139    * @return this SelectionBuilder
140    */
setTitle(@ullable CharSequence title)141   public SelectionBuilder setTitle(@Nullable CharSequence title) {
142     mTitle = title;
143     return this;
144   }
145 
146   /**
147    * Sets the subtitle.
148    *
149    * @param subtitle the subtitle
150    * @return this SelectionBuilder
151    */
setSubtitle(@ullable CharSequence subtitle)152   public SelectionBuilder setSubtitle(@Nullable CharSequence subtitle) {
153     mSubtitle = subtitle;
154     return this;
155   }
156 
157   /**
158    * Sets the content description.
159    *
160    * @param contentDescription the content description
161    * @return this SelectionBuilder
162    */
setContentDescription(@ullable CharSequence contentDescription)163   public SelectionBuilder setContentDescription(@Nullable CharSequence contentDescription) {
164     mContentDescription = contentDescription;
165     return this;
166   }
167 
168   /**
169    * Sets the layout direction.
170    *
171    * @param layoutDirection the layout direction
172    * @return this SelectionBuilder
173    */
setLayoutDirection( @om.android.tv.twopanelsettings.slices.compat.builders.ListBuilder.LayoutDirection int layoutDirection)174   public SelectionBuilder setLayoutDirection(
175       @com.android.tv.twopanelsettings.slices.compat.builders.ListBuilder.LayoutDirection
176           int layoutDirection) {
177     mLayoutDirection = layoutDirection;
178     return this;
179   }
180 
181   /** */
182   // @RestrictTo(LIBRARY)
getOptions()183   public List<Pair<String, CharSequence>> getOptions() {
184     return mOptions;
185   }
186 
187   /** */
188   // @RestrictTo(LIBRARY)
getPrimaryAction()189   public SliceAction getPrimaryAction() {
190     return mPrimaryAction;
191   }
192 
193   /** */
194   // @RestrictTo(LIBRARY)
getInputAction()195   public Parcelable getInputAction() {
196     return mInputAction;
197   }
198 
199   /** */
200   // @RestrictTo(LIBRARY)
getSelectedOption()201   public String getSelectedOption() {
202     return mSelectedOption;
203   }
204 
205   /** */
206   // @RestrictTo(LIBRARY)
getTitle()207   public CharSequence getTitle() {
208     return mTitle;
209   }
210 
211   /** */
212   // @RestrictTo(LIBRARY)
getSubtitle()213   public CharSequence getSubtitle() {
214     return mSubtitle;
215   }
216 
217   /** */
218   // @RestrictTo(LIBRARY)
getContentDescription()219   public CharSequence getContentDescription() {
220     return mContentDescription;
221   }
222 
223   /** */
224   // @RestrictTo(LIBRARY)
getLayoutDirection()225   public int getLayoutDirection() {
226     return mLayoutDirection;
227   }
228 
229   /** */
230   // @RestrictTo(LIBRARY)
check()231   public void check() {
232     if (getPrimaryAction() == null) {
233       throw new IllegalArgumentException("primaryAction must be set");
234     }
235     if (getInputAction() == null) {
236       throw new IllegalArgumentException("inputAction must be set");
237     }
238     if (mSelectedOption != null && !mOptionKeys.contains(mSelectedOption)) {
239       throw new IllegalArgumentException("selectedOption must be present in options");
240     }
241   }
242 }
243