blob: 124df32af5e0c59e3f0fde5632dd302189ed980c [file] [log] [blame]
Matt Pietala635bd12020-02-03 13:36:18 -05001/*
2 * Copyright (C) 2020 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 com.android.systemui.controls.ui
18
Matt Pietala103a942020-03-13 12:10:35 -040019import android.annotation.ColorRes
Matt Pietal53a8bbd2020-03-05 16:10:34 -050020import android.annotation.MainThread
21import android.content.ComponentName
22import android.content.Context
23import android.graphics.drawable.Drawable
Matt Pietala635bd12020-02-03 13:36:18 -050024import android.service.controls.DeviceTypes
25import android.service.controls.templates.TemperatureControlTemplate
Matt Pietal53a8bbd2020-03-05 16:10:34 -050026import android.util.ArrayMap
27import android.util.SparseArray
Matt Pietala635bd12020-02-03 13:36:18 -050028
29import com.android.systemui.R
30
31data class IconState(val disabledResourceId: Int, val enabledResourceId: Int) {
32 operator fun get(state: Boolean): Int {
33 return if (state) {
34 enabledResourceId
35 } else {
36 disabledResourceId
37 }
38 }
39}
40
Matt Pietala103a942020-03-13 12:10:35 -040041data class RenderInfo(
42 val icon: Drawable,
43 val foreground: Int,
44 @ColorRes val enabledBackground: Int
45) {
Matt Pietala635bd12020-02-03 13:36:18 -050046 companion object {
Matt Pietal53a8bbd2020-03-05 16:10:34 -050047 const val APP_ICON_ID = -1
48 private val iconMap = SparseArray<Drawable>()
49 private val appIconMap = ArrayMap<ComponentName, Drawable>()
50
51 @MainThread
52 fun lookup(
53 context: Context,
54 componentName: ComponentName,
55 deviceType: Int,
56 enabled: Boolean,
57 offset: Int = 0
58 ): RenderInfo {
Matt Pietal38180a42020-04-07 14:59:05 -040059 val key = if (offset > 0) {
Matt Pietal53a8bbd2020-03-05 16:10:34 -050060 deviceType * BUCKET_SIZE + offset
61 } else deviceType
62
Matt Pietal38180a42020-04-07 14:59:05 -040063 val (fg, bg) = deviceColorMap.getValue(key)
64 val iconState = deviceIconMap.getValue(key)
Matt Pietal53a8bbd2020-03-05 16:10:34 -050065 val resourceId = iconState[enabled]
Matt Pietalf8cc0fa2020-03-26 08:48:50 -040066 var icon: Drawable?
Matt Pietal53a8bbd2020-03-05 16:10:34 -050067 if (resourceId == APP_ICON_ID) {
68 icon = appIconMap.get(componentName)
69 if (icon == null) {
70 icon = context.resources
Matt Pietal1ee1db82020-04-08 16:13:02 -040071 .getDrawable(R.drawable.ic_device_unknown_on, null)
Matt Pietal53a8bbd2020-03-05 16:10:34 -050072 appIconMap.put(componentName, icon)
73 }
74 } else {
75 icon = iconMap.get(resourceId)
76 if (icon == null) {
77 icon = context.resources.getDrawable(resourceId, null)
Matt Pietala103a942020-03-13 12:10:35 -040078 icon.mutate()
Matt Pietal53a8bbd2020-03-05 16:10:34 -050079 iconMap.put(resourceId, icon)
80 }
81 }
82 return RenderInfo(icon!!, fg, bg)
Matt Pietala635bd12020-02-03 13:36:18 -050083 }
84
Matt Pietal53a8bbd2020-03-05 16:10:34 -050085 fun registerComponentIcon(componentName: ComponentName, icon: Drawable) {
86 appIconMap.put(componentName, icon)
87 }
88
89 fun clearCache() {
90 iconMap.clear()
91 appIconMap.clear()
Matt Pietala635bd12020-02-03 13:36:18 -050092 }
93 }
94}
95
96private const val BUCKET_SIZE = 1000
97private const val THERMOSTAT_RANGE = DeviceTypes.TYPE_THERMOSTAT * BUCKET_SIZE
98
Fabian Kozynski5fc5f6b2020-02-03 15:21:14 -050099private val deviceColorMap = mapOf<Int, Pair<Int, Int>>(
Matt Pietala635bd12020-02-03 13:36:18 -0500100 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to
Matt Pietala103a942020-03-13 12:10:35 -0400101 Pair(R.color.thermo_heat_foreground, R.color.control_enabled_thermo_heat_background),
Matt Pietala635bd12020-02-03 13:36:18 -0500102 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to
Matt Pietala103a942020-03-13 12:10:35 -0400103 Pair(R.color.thermo_cool_foreground, R.color.control_enabled_thermo_cool_background),
104 DeviceTypes.TYPE_LIGHT
105 to Pair(R.color.light_foreground, R.color.control_enabled_light_background)
Matt Pietala635bd12020-02-03 13:36:18 -0500106).withDefault {
Matt Pietala103a942020-03-13 12:10:35 -0400107 Pair(R.color.control_foreground, R.color.control_enabled_default_background)
Matt Pietala635bd12020-02-03 13:36:18 -0500108}
109
Fabian Kozynski5fc5f6b2020-02-03 15:21:14 -0500110private val deviceIconMap = mapOf<Int, IconState>(
Matt Pietala635bd12020-02-03 13:36:18 -0500111 THERMOSTAT_RANGE to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400112 R.drawable.ic_device_thermostat_off,
113 R.drawable.ic_device_thermostat_on
Matt Pietala635bd12020-02-03 13:36:18 -0500114 ),
115 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_OFF) to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400116 R.drawable.ic_device_thermostat_off,
117 R.drawable.ic_device_thermostat_on
Matt Pietala635bd12020-02-03 13:36:18 -0500118 ),
119 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400120 R.drawable.ic_device_thermostat_off,
121 R.drawable.ic_device_thermostat_on
Matt Pietala635bd12020-02-03 13:36:18 -0500122 ),
123 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400124 R.drawable.ic_device_thermostat_off,
125 R.drawable.ic_device_thermostat_on
Matt Pietala635bd12020-02-03 13:36:18 -0500126 ),
127 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT_COOL) to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400128 R.drawable.ic_device_thermostat_off,
129 R.drawable.ic_device_thermostat_on
Matt Pietala635bd12020-02-03 13:36:18 -0500130 ),
131 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_ECO) to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400132 R.drawable.ic_device_thermostat_off,
133 R.drawable.ic_device_thermostat_on
Matt Pietala635bd12020-02-03 13:36:18 -0500134 ),
135 DeviceTypes.TYPE_THERMOSTAT to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400136 R.drawable.ic_device_thermostat_off,
137 R.drawable.ic_device_thermostat_on
Matt Pietala635bd12020-02-03 13:36:18 -0500138 ),
139 DeviceTypes.TYPE_LIGHT to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400140 R.drawable.ic_device_light_off,
141 R.drawable.ic_device_light_on
Matt Pietala635bd12020-02-03 13:36:18 -0500142 ),
143 DeviceTypes.TYPE_CAMERA to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400144 R.drawable.ic_device_camera_off,
145 R.drawable.ic_device_camera_on
Matt Pietala635bd12020-02-03 13:36:18 -0500146 ),
147 DeviceTypes.TYPE_LOCK to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400148 R.drawable.ic_device_lock_off,
149 R.drawable.ic_device_lock_on
Matt Pietala635bd12020-02-03 13:36:18 -0500150 ),
151 DeviceTypes.TYPE_SWITCH to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400152 R.drawable.ic_device_switch_off,
153 R.drawable.ic_device_switch_on
Matt Pietala635bd12020-02-03 13:36:18 -0500154 ),
155 DeviceTypes.TYPE_OUTLET to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400156 R.drawable.ic_device_outlet_off,
157 R.drawable.ic_device_outlet_on
Matt Pietalfee8c472020-02-05 11:59:00 -0500158 ),
159 DeviceTypes.TYPE_VACUUM to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400160 R.drawable.ic_device_vacuum_off,
161 R.drawable.ic_device_vacuum_on
Matt Pietalfee8c472020-02-05 11:59:00 -0500162 ),
163 DeviceTypes.TYPE_MOP to IconState(
Matt Pietalb5cb4422020-03-26 10:56:36 -0400164 R.drawable.ic_device_mop_off,
165 R.drawable.ic_device_mop_on
166 ),
167 DeviceTypes.TYPE_AIR_FRESHENER to IconState(
168 R.drawable.ic_device_air_freshener_off,
169 R.drawable.ic_device_air_freshener_on
170 ),
171 DeviceTypes.TYPE_AIR_PURIFIER to IconState(
172 R.drawable.ic_device_air_purifier_off,
173 R.drawable.ic_device_air_purifier_on
174 ),
175 DeviceTypes.TYPE_FAN to IconState(
176 R.drawable.ic_device_fan_off,
177 R.drawable.ic_device_fan_on
178 ),
179 DeviceTypes.TYPE_HOOD to IconState(
180 R.drawable.ic_device_hood_off,
181 R.drawable.ic_device_hood_on
182 ),
183 DeviceTypes.TYPE_KETTLE to IconState(
184 R.drawable.ic_device_kettle_off,
185 R.drawable.ic_device_kettle_on
186 ),
187 DeviceTypes.TYPE_MICROWAVE to IconState(
188 R.drawable.ic_device_microwave_off,
189 R.drawable.ic_device_microwave_on
190 ),
191 DeviceTypes.TYPE_REMOTE_CONTROL to IconState(
192 R.drawable.ic_device_remote_control_off,
193 R.drawable.ic_device_remote_control_on
194 ),
195 DeviceTypes.TYPE_SET_TOP to IconState(
196 R.drawable.ic_device_set_top_off,
197 R.drawable.ic_device_set_top_on
198 ),
199 DeviceTypes.TYPE_STYLER to IconState(
200 R.drawable.ic_device_styler_off,
201 R.drawable.ic_device_styler_on
202 ),
203 DeviceTypes.TYPE_TV to IconState(
204 R.drawable.ic_device_tv_off,
205 R.drawable.ic_device_tv_on
206 ),
207 DeviceTypes.TYPE_WATER_HEATER to IconState(
208 R.drawable.ic_device_water_heater_off,
209 R.drawable.ic_device_water_heater_on
210 ),
211 DeviceTypes.TYPE_DISHWASHER to IconState(
212 R.drawable.ic_device_dishwasher_off,
213 R.drawable.ic_device_dishwasher_on
214 ),
215 DeviceTypes.TYPE_MULTICOOKER to IconState(
216 R.drawable.ic_device_multicooker_off,
217 R.drawable.ic_device_multicooker_on
218 ),
219 DeviceTypes.TYPE_SPRINKLER to IconState(
220 R.drawable.ic_device_sprinkler_off,
221 R.drawable.ic_device_sprinkler_on
222 ),
223 DeviceTypes.TYPE_WASHER to IconState(
224 R.drawable.ic_device_washer_off,
225 R.drawable.ic_device_washer_on
226 ),
227 DeviceTypes.TYPE_BLINDS to IconState(
228 R.drawable.ic_device_blinds_off,
229 R.drawable.ic_device_blinds_on
230 ),
231 DeviceTypes.TYPE_DRAWER to IconState(
232 R.drawable.ic_device_drawer_off,
233 R.drawable.ic_device_drawer_on
234 ),
235 DeviceTypes.TYPE_GARAGE to IconState(
236 R.drawable.ic_device_garage_off,
237 R.drawable.ic_device_garage_on
238 ),
239 DeviceTypes.TYPE_GATE to IconState(
240 R.drawable.ic_device_gate_off,
241 R.drawable.ic_device_gate_on
242 ),
243 DeviceTypes.TYPE_PERGOLA to IconState(
244 R.drawable.ic_device_pergola_off,
245 R.drawable.ic_device_pergola_on
246 ),
247 DeviceTypes.TYPE_WINDOW to IconState(
248 R.drawable.ic_device_window_off,
249 R.drawable.ic_device_window_on
250 ),
251 DeviceTypes.TYPE_VALVE to IconState(
252 R.drawable.ic_device_valve_off,
253 R.drawable.ic_device_valve_on
254 ),
255 DeviceTypes.TYPE_SECURITY_SYSTEM to IconState(
256 R.drawable.ic_device_security_system_off,
257 R.drawable.ic_device_security_system_on
258 ),
259 DeviceTypes.TYPE_REFRIGERATOR to IconState(
260 R.drawable.ic_device_refrigerator_off,
261 R.drawable.ic_device_refrigerator_on
262 ),
263 DeviceTypes.TYPE_DOORBELL to IconState(
264 R.drawable.ic_device_doorbell_off,
265 R.drawable.ic_device_doorbell_on
Matt Pietal53a8bbd2020-03-05 16:10:34 -0500266 ),
267 DeviceTypes.TYPE_ROUTINE to IconState(
268 RenderInfo.APP_ICON_ID,
269 RenderInfo.APP_ICON_ID
Matt Pietal1ee1db82020-04-08 16:13:02 -0400270 ),
271 DeviceTypes.TYPE_AC_HEATER to IconState(
272 R.drawable.ic_device_thermostat_off,
273 R.drawable.ic_device_thermostat_on
274 ),
275 DeviceTypes.TYPE_AC_UNIT to IconState(
276 R.drawable.ic_device_thermostat_off,
277 R.drawable.ic_device_thermostat_on
278 ),
279 DeviceTypes.TYPE_COFFEE_MAKER to IconState(
280 R.drawable.ic_device_kettle_off,
281 R.drawable.ic_device_kettle_on
282 ),
283 DeviceTypes.TYPE_DEHUMIDIFIER to IconState(
284 R.drawable.ic_device_air_freshener_off,
285 R.drawable.ic_device_air_freshener_on
286 ),
287 DeviceTypes.TYPE_RADIATOR to IconState(
288 R.drawable.ic_device_thermostat_off,
289 R.drawable.ic_device_thermostat_on
290 ),
291 DeviceTypes.TYPE_STANDMIXER to IconState(
292 R.drawable.ic_device_cooking_off,
293 R.drawable.ic_device_cooking_on
294 ),
295 DeviceTypes.TYPE_DISPLAY to IconState(
296 R.drawable.ic_device_display_off,
297 R.drawable.ic_device_display_on
298 ),
299 DeviceTypes.TYPE_DRYER to IconState(
300 R.drawable.ic_device_washer_off,
301 R.drawable.ic_device_washer_on
302 ),
303 DeviceTypes.TYPE_MOWER to IconState(
304 R.drawable.ic_device_outdoor_garden_off,
305 R.drawable.ic_device_outdoor_garden_on
306 ),
307 DeviceTypes.TYPE_SHOWER to IconState(
308 R.drawable.ic_device_water_off,
309 R.drawable.ic_device_water_on
310 ),
311 DeviceTypes.TYPE_AWNING to IconState(
312 R.drawable.ic_device_pergola_off,
313 R.drawable.ic_device_pergola_on
314 ),
315 DeviceTypes.TYPE_CLOSET to IconState(
316 R.drawable.ic_device_drawer_off,
317 R.drawable.ic_device_drawer_on
318 ),
319 DeviceTypes.TYPE_CURTAIN to IconState(
320 R.drawable.ic_device_blinds_off,
321 R.drawable.ic_device_blinds_on
322 ),
323 DeviceTypes.TYPE_DOOR to IconState(
324 R.drawable.ic_device_door_off,
325 R.drawable.ic_device_door_on
326 ),
327 DeviceTypes.TYPE_SHUTTER to IconState(
328 R.drawable.ic_device_window_off,
329 R.drawable.ic_device_window_on
330 ),
331 DeviceTypes.TYPE_HEATER to IconState(
332 R.drawable.ic_device_thermostat_off,
333 R.drawable.ic_device_thermostat_on
Matt Pietala635bd12020-02-03 13:36:18 -0500334 )
335).withDefault {
336 IconState(
Matt Pietal1ee1db82020-04-08 16:13:02 -0400337 R.drawable.ic_device_unknown_off,
338 R.drawable.ic_device_unknown_on
Matt Pietala635bd12020-02-03 13:36:18 -0500339 )
340}