blob: 27e46497b20aa0306e6dc81db9a204eacae157fd [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 Pietala635bd12020-02-03 13:36:18 -050059 val (fg, bg) = deviceColorMap.getValue(deviceType)
Matt Pietal53a8bbd2020-03-05 16:10:34 -050060
61 val iconKey = if (offset > 0) {
62 deviceType * BUCKET_SIZE + offset
63 } else deviceType
64
65 val iconState = deviceIconMap.getValue(iconKey)
66 val resourceId = iconState[enabled]
67 var icon: Drawable? = null
68 if (resourceId == APP_ICON_ID) {
69 icon = appIconMap.get(componentName)
70 if (icon == null) {
71 icon = context.resources
72 .getDrawable(R.drawable.ic_device_unknown_gm2_24px, null)
73 appIconMap.put(componentName, icon)
74 }
75 } else {
76 icon = iconMap.get(resourceId)
77 if (icon == null) {
78 icon = context.resources.getDrawable(resourceId, null)
Matt Pietala103a942020-03-13 12:10:35 -040079 icon.mutate()
Matt Pietal53a8bbd2020-03-05 16:10:34 -050080 iconMap.put(resourceId, icon)
81 }
82 }
83 return RenderInfo(icon!!, fg, bg)
Matt Pietala635bd12020-02-03 13:36:18 -050084 }
85
Matt Pietal53a8bbd2020-03-05 16:10:34 -050086 fun registerComponentIcon(componentName: ComponentName, icon: Drawable) {
87 appIconMap.put(componentName, icon)
88 }
89
90 fun clearCache() {
91 iconMap.clear()
92 appIconMap.clear()
Matt Pietala635bd12020-02-03 13:36:18 -050093 }
94 }
95}
96
97private const val BUCKET_SIZE = 1000
98private const val THERMOSTAT_RANGE = DeviceTypes.TYPE_THERMOSTAT * BUCKET_SIZE
99
Fabian Kozynski5fc5f6b2020-02-03 15:21:14 -0500100private val deviceColorMap = mapOf<Int, Pair<Int, Int>>(
Matt Pietala635bd12020-02-03 13:36:18 -0500101 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to
Matt Pietala103a942020-03-13 12:10:35 -0400102 Pair(R.color.thermo_heat_foreground, R.color.control_enabled_thermo_heat_background),
Matt Pietala635bd12020-02-03 13:36:18 -0500103 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to
Matt Pietala103a942020-03-13 12:10:35 -0400104 Pair(R.color.thermo_cool_foreground, R.color.control_enabled_thermo_cool_background),
105 DeviceTypes.TYPE_LIGHT
106 to Pair(R.color.light_foreground, R.color.control_enabled_light_background)
Matt Pietala635bd12020-02-03 13:36:18 -0500107).withDefault {
Matt Pietala103a942020-03-13 12:10:35 -0400108 Pair(R.color.control_foreground, R.color.control_enabled_default_background)
Matt Pietala635bd12020-02-03 13:36:18 -0500109}
110
Fabian Kozynski5fc5f6b2020-02-03 15:21:14 -0500111private val deviceIconMap = mapOf<Int, IconState>(
Matt Pietala635bd12020-02-03 13:36:18 -0500112 THERMOSTAT_RANGE to IconState(
113 R.drawable.ic_device_thermostat_gm2_24px,
114 R.drawable.ic_device_thermostat_gm2_24px
115 ),
116 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_OFF) to IconState(
117 R.drawable.ic_device_thermostat_gm2_24px,
118 R.drawable.ic_device_thermostat_gm2_24px
119 ),
120 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to IconState(
121 R.drawable.ic_device_thermostat_gm2_24px,
122 R.drawable.ic_device_thermostat_gm2_24px
123 ),
124 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to IconState(
125 R.drawable.ic_device_thermostat_gm2_24px,
126 R.drawable.ic_device_thermostat_gm2_24px
127 ),
128 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT_COOL) to IconState(
129 R.drawable.ic_device_thermostat_gm2_24px,
130 R.drawable.ic_device_thermostat_gm2_24px
131 ),
132 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_ECO) to IconState(
133 R.drawable.ic_device_thermostat_gm2_24px,
134 R.drawable.ic_device_thermostat_gm2_24px
135 ),
136 DeviceTypes.TYPE_THERMOSTAT to IconState(
137 R.drawable.ic_device_thermostat_gm2_24px,
138 R.drawable.ic_device_thermostat_gm2_24px
139 ),
140 DeviceTypes.TYPE_LIGHT to IconState(
141 R.drawable.ic_light_off_gm2_24px,
142 R.drawable.ic_lightbulb_outline_gm2_24px
143 ),
144 DeviceTypes.TYPE_CAMERA to IconState(
145 R.drawable.ic_videocam_gm2_24px,
146 R.drawable.ic_videocam_gm2_24px
147 ),
148 DeviceTypes.TYPE_LOCK to IconState(
149 R.drawable.ic_lock_open_gm2_24px,
150 R.drawable.ic_lock_gm2_24px
151 ),
152 DeviceTypes.TYPE_SWITCH to IconState(
153 R.drawable.ic_switches_gm2_24px,
154 R.drawable.ic_switches_gm2_24px
155 ),
156 DeviceTypes.TYPE_OUTLET to IconState(
157 R.drawable.ic_power_off_gm2_24px,
158 R.drawable.ic_power_gm2_24px
Matt Pietalfee8c472020-02-05 11:59:00 -0500159 ),
160 DeviceTypes.TYPE_VACUUM to IconState(
161 R.drawable.ic_vacuum_gm2_24px,
162 R.drawable.ic_vacuum_gm2_24px
163 ),
164 DeviceTypes.TYPE_MOP to IconState(
165 R.drawable.ic_vacuum_gm2_24px,
166 R.drawable.ic_vacuum_gm2_24px
Matt Pietal53a8bbd2020-03-05 16:10:34 -0500167 ),
168 DeviceTypes.TYPE_ROUTINE to IconState(
169 RenderInfo.APP_ICON_ID,
170 RenderInfo.APP_ICON_ID
Matt Pietala635bd12020-02-03 13:36:18 -0500171 )
172).withDefault {
173 IconState(
Matt Pietalfee8c472020-02-05 11:59:00 -0500174 R.drawable.ic_device_unknown_gm2_24px,
175 R.drawable.ic_device_unknown_gm2_24px
Matt Pietala635bd12020-02-03 13:36:18 -0500176 )
177}