blob: 1e16273c455b64e5796c83792e34db09681b3680 [file] [log] [blame]
Alan Viverette3da604b2020-06-10 18:34:39 +00001/*
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
17package android.service.controls.templates;
18
19import android.annotation.CallSuper;
20import android.annotation.IntDef;
21import android.annotation.NonNull;
22import android.annotation.Nullable;
23import android.os.Bundle;
24import android.service.controls.Control;
25import android.service.controls.actions.ControlAction;
26import android.util.Log;
27
28import com.android.internal.util.Preconditions;
29
30import java.lang.annotation.Retention;
31import java.lang.annotation.RetentionPolicy;
32
33/**
34 * An abstract input template for a {@link Control}.
35 *
36 * Specifies what layout is presented to the user for a given {@link Control}.
37 * <p>
38 * Some instances of {@link Control} can originate actions (via user interaction) to modify its
39 * associated state. The actions available to a given {@link Control} are determined by its
40 * {@link ControlTemplate}.
41 * @see ControlAction
42 */
43public abstract class ControlTemplate {
44
45 private static final String TAG = "ControlTemplate";
46
47 private static final String KEY_TEMPLATE_ID = "key_template_id";
48 private static final String KEY_TEMPLATE_TYPE = "key_template_type";
49
50 /**
51 * Singleton representing a {@link Control} with no input.
52 * @hide
53 */
54 public static final @NonNull ControlTemplate NO_TEMPLATE = new ControlTemplate("") {
55 @Override
56 public int getTemplateType() {
57 return TYPE_NO_TEMPLATE;
58 }
59 };
60
61 /**
62 * Object returned when there is an unparcelling error.
63 * @hide
64 */
65 private static final @NonNull ControlTemplate ERROR_TEMPLATE = new ControlTemplate("") {
66 @Override
67 public int getTemplateType() {
68 return TYPE_ERROR;
69 }
70 };
71
72 /**
73 * @hide
74 */
75 @Retention(RetentionPolicy.SOURCE)
76 @IntDef({
77 TYPE_ERROR,
78 TYPE_NO_TEMPLATE,
79 TYPE_TOGGLE,
80 TYPE_RANGE,
81 TYPE_TOGGLE_RANGE,
82 TYPE_TEMPERATURE,
83 TYPE_STATELESS
84 })
85 public @interface TemplateType {}
86
87 /**
88 * Type identifier of the template returned by {@link #getErrorTemplate()}.
89 */
90 public static final @TemplateType int TYPE_ERROR = -1;
91
92 /**
93 * Type identifier of {@link ControlTemplate#getNoTemplateObject}.
94 */
95 public static final @TemplateType int TYPE_NO_TEMPLATE = 0;
96
97 /**
98 * Type identifier of {@link ToggleTemplate}.
99 */
100 public static final @TemplateType int TYPE_TOGGLE = 1;
101
102 /**
103 * Type identifier of {@link RangeTemplate}.
104 */
105 public static final @TemplateType int TYPE_RANGE = 2;
106
107 /**
108 * Type identifier of {@link ToggleRangeTemplate}.
109 */
110 public static final @TemplateType int TYPE_TOGGLE_RANGE = 6;
111
112 /**
113 * Type identifier of {@link TemperatureControlTemplate}.
114 */
115 public static final @TemplateType int TYPE_TEMPERATURE = 7;
116
117 /**
118 * Type identifier of {@link StatelessTemplate}.
119 */
120 public static final @TemplateType int TYPE_STATELESS = 8;
121
122 private @NonNull final String mTemplateId;
123
124 /**
125 * @return the identifier for this object.
126 */
127 @NonNull
128 public String getTemplateId() {
129 return mTemplateId;
130 }
131
132 /**
133 * The {@link TemplateType} associated with this class.
134 */
135 public abstract @TemplateType int getTemplateType();
136
137 /**
138 * Obtain a {@link Bundle} describing this object populated with data.
139 * @return a {@link Bundle} containing the data that represents this object.
140 * @hide
141 */
142 @CallSuper
143 @NonNull
144 Bundle getDataBundle() {
145 Bundle b = new Bundle();
146 b.putInt(KEY_TEMPLATE_TYPE, getTemplateType());
147 b.putString(KEY_TEMPLATE_ID, mTemplateId);
148 return b;
149 }
150
151 private ControlTemplate() {
152 mTemplateId = "";
153 }
154
155 /**
156 * @param b
157 * @hide
158 */
159 ControlTemplate(@NonNull Bundle b) {
160 mTemplateId = b.getString(KEY_TEMPLATE_ID);
161 }
162
163 /**
164 * @hide
165 */
166 ControlTemplate(@NonNull String templateId) {
167 Preconditions.checkNotNull(templateId);
168 mTemplateId = templateId;
169 }
170
171 /**
172 *
173 * @param bundle
174 * @return
175 * @hide
176 */
177 @NonNull
178 static ControlTemplate createTemplateFromBundle(@Nullable Bundle bundle) {
179 if (bundle == null) {
180 Log.e(TAG, "Null bundle");
181 return ERROR_TEMPLATE;
182 }
183 int type = bundle.getInt(KEY_TEMPLATE_TYPE, TYPE_ERROR);
184 try {
185 switch (type) {
186 case TYPE_TOGGLE:
187 return new ToggleTemplate(bundle);
188 case TYPE_RANGE:
189 return new RangeTemplate(bundle);
190 case TYPE_TOGGLE_RANGE:
191 return new ToggleRangeTemplate(bundle);
192 case TYPE_TEMPERATURE:
193 return new TemperatureControlTemplate(bundle);
194 case TYPE_STATELESS:
195 return new StatelessTemplate(bundle);
196 case TYPE_NO_TEMPLATE:
197 return NO_TEMPLATE;
198 case TYPE_ERROR:
199 default:
200 return ERROR_TEMPLATE;
201 }
202 } catch (Exception e) {
203 Log.e(TAG, "Error creating template", e);
204 return ERROR_TEMPLATE;
205 }
206 }
207
208 /**
209 * @return a singleton {@link ControlTemplate} used for indicating an error in unparceling.
210 */
211 @NonNull
212 public static ControlTemplate getErrorTemplate() {
213 return ERROR_TEMPLATE;
214 }
215
216 /**
217 * Get a singleton {@link ControlTemplate} that has no features.
218 *
219 * This template has no distinctive field, not even an identifier. Used for a {@link Control}
220 * that accepts no type of input, or when there is no known state.
221 *
222 * @return a singleton {@link ControlTemplate} to indicate no specific template is used by
223 * this {@link Control}
224 */
225 @NonNull
226 public static ControlTemplate getNoTemplateObject() {
227 return NO_TEMPLATE;
228 }
229
230}