1 /* 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 17 package com.android.systemui.controls.ui 18 19 import android.annotation.ColorRes 20 import android.annotation.MainThread 21 import android.content.ComponentName 22 import android.content.Context 23 import android.graphics.drawable.Drawable 24 import android.service.controls.DeviceTypes 25 import android.service.controls.templates.TemperatureControlTemplate 26 import android.util.ArrayMap 27 import android.util.SparseArray 28 29 import com.android.systemui.R 30 31 data class RenderInfo( 32 val icon: Drawable, 33 val foreground: Int, 34 @ColorRes val enabledBackground: Int 35 ) { 36 companion object { 37 const val APP_ICON_ID = -1 38 const val ERROR_ICON = -1000 39 private val iconMap = SparseArray<Drawable>() 40 private val appIconMap = ArrayMap<ComponentName, Drawable>() 41 42 @MainThread 43 fun lookup( 44 context: Context, 45 componentName: ComponentName, 46 deviceType: Int, 47 offset: Int = 0 48 ): RenderInfo { 49 val key = if (offset > 0) { 50 deviceType * BUCKET_SIZE + offset 51 } else deviceType 52 53 val (fg, bg) = deviceColorMap.getValue(key) 54 val resourceId = deviceIconMap.getValue(key) 55 var icon: Drawable? 56 if (resourceId == APP_ICON_ID) { 57 icon = appIconMap.get(componentName) 58 if (icon == null) { 59 icon = context.resources 60 .getDrawable(R.drawable.ic_device_unknown_on, null) 61 appIconMap.put(componentName, icon) 62 } 63 } else { 64 icon = iconMap.get(resourceId) 65 if (icon == null) { 66 icon = context.resources.getDrawable(resourceId, null) 67 iconMap.put(resourceId, icon) 68 } 69 } 70 return RenderInfo( 71 checkNotNull(icon?.constantState).newDrawable(context.resources), fg, bg) 72 } 73 74 fun registerComponentIcon(componentName: ComponentName, icon: Drawable) { 75 appIconMap.put(componentName, icon) 76 } 77 78 fun clearCache() { 79 iconMap.clear() 80 appIconMap.clear() 81 } 82 } 83 } 84 85 private const val BUCKET_SIZE = 1000 86 private const val THERMOSTAT_RANGE = DeviceTypes.TYPE_THERMOSTAT * BUCKET_SIZE 87 88 private val deviceColorMap = mapOf<Int, Pair<Int, Int>>( 89 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_OFF) to 90 Pair(R.color.control_default_foreground, R.color.control_default_background), 91 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to 92 Pair(R.color.thermo_heat_foreground, R.color.control_enabled_thermo_heat_background), 93 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to 94 Pair(R.color.thermo_cool_foreground, R.color.control_enabled_thermo_cool_background), 95 DeviceTypes.TYPE_LIGHT 96 to Pair(R.color.light_foreground, R.color.control_enabled_light_background), 97 DeviceTypes.TYPE_CAMERA 98 to Pair(R.color.camera_foreground, R.color.control_enabled_default_background) 99 ).withDefault { 100 Pair(R.color.control_foreground, R.color.control_enabled_default_background) 101 } 102 103 private val deviceIconMap = mapOf<Int, Int>( 104 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_OFF) to 105 R.drawable.ic_device_thermostat_off, 106 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to 107 R.drawable.ic_device_thermostat, 108 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to 109 R.drawable.ic_device_thermostat, 110 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT_COOL) to 111 R.drawable.ic_device_thermostat, 112 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_ECO) to 113 R.drawable.ic_device_thermostat_off, 114 DeviceTypes.TYPE_THERMOSTAT to R.drawable.ic_device_thermostat, 115 DeviceTypes.TYPE_LIGHT to R.drawable.ic_device_light, 116 DeviceTypes.TYPE_CAMERA to R.drawable.ic_device_camera, 117 DeviceTypes.TYPE_LOCK to R.drawable.ic_device_lock, 118 DeviceTypes.TYPE_SWITCH to R.drawable.ic_device_switch, 119 DeviceTypes.TYPE_OUTLET to R.drawable.ic_device_outlet, 120 DeviceTypes.TYPE_VACUUM to R.drawable.ic_device_vacuum, 121 DeviceTypes.TYPE_MOP to R.drawable.ic_device_mop, 122 DeviceTypes.TYPE_AIR_FRESHENER to R.drawable.ic_device_air_freshener, 123 DeviceTypes.TYPE_AIR_PURIFIER to R.drawable.ic_device_air_purifier, 124 DeviceTypes.TYPE_FAN to R.drawable.ic_device_fan, 125 DeviceTypes.TYPE_HOOD to R.drawable.ic_device_hood, 126 DeviceTypes.TYPE_KETTLE to R.drawable.ic_device_kettle, 127 DeviceTypes.TYPE_MICROWAVE to R.drawable.ic_device_microwave, 128 DeviceTypes.TYPE_REMOTE_CONTROL to R.drawable.ic_device_remote_control, 129 DeviceTypes.TYPE_SET_TOP to R.drawable.ic_device_set_top, 130 DeviceTypes.TYPE_STYLER to R.drawable.ic_device_styler, 131 DeviceTypes.TYPE_TV to R.drawable.ic_device_tv, 132 DeviceTypes.TYPE_WATER_HEATER to R.drawable.ic_device_water_heater, 133 DeviceTypes.TYPE_DISHWASHER to R.drawable.ic_device_dishwasher, 134 DeviceTypes.TYPE_MULTICOOKER to R.drawable.ic_device_multicooker, 135 DeviceTypes.TYPE_SPRINKLER to R.drawable.ic_device_sprinkler, 136 DeviceTypes.TYPE_WASHER to R.drawable.ic_device_washer, 137 DeviceTypes.TYPE_BLINDS to R.drawable.ic_device_blinds, 138 DeviceTypes.TYPE_DRAWER to R.drawable.ic_device_drawer, 139 DeviceTypes.TYPE_GARAGE to R.drawable.ic_device_garage, 140 DeviceTypes.TYPE_GATE to R.drawable.ic_device_gate, 141 DeviceTypes.TYPE_PERGOLA to R.drawable.ic_device_pergola, 142 DeviceTypes.TYPE_WINDOW to R.drawable.ic_device_window, 143 DeviceTypes.TYPE_VALVE to R.drawable.ic_device_valve, 144 DeviceTypes.TYPE_SECURITY_SYSTEM to R.drawable.ic_device_security_system, 145 DeviceTypes.TYPE_REFRIGERATOR to R.drawable.ic_device_refrigerator, 146 DeviceTypes.TYPE_DOORBELL to R.drawable.ic_device_doorbell, 147 DeviceTypes.TYPE_ROUTINE to RenderInfo.APP_ICON_ID, 148 DeviceTypes.TYPE_AC_HEATER to R.drawable.ic_device_thermostat, 149 DeviceTypes.TYPE_AC_UNIT to R.drawable.ic_device_thermostat, 150 DeviceTypes.TYPE_COFFEE_MAKER to R.drawable.ic_device_kettle, 151 DeviceTypes.TYPE_DEHUMIDIFIER to R.drawable.ic_device_air_freshener, 152 DeviceTypes.TYPE_RADIATOR to R.drawable.ic_device_thermostat, 153 DeviceTypes.TYPE_STANDMIXER to R.drawable.ic_device_cooking, 154 DeviceTypes.TYPE_DISPLAY to R.drawable.ic_device_display, 155 DeviceTypes.TYPE_DRYER to R.drawable.ic_device_washer, 156 DeviceTypes.TYPE_MOWER to R.drawable.ic_device_outdoor_garden, 157 DeviceTypes.TYPE_SHOWER to R.drawable.ic_device_water, 158 DeviceTypes.TYPE_AWNING to R.drawable.ic_device_pergola, 159 DeviceTypes.TYPE_CLOSET to R.drawable.ic_device_drawer, 160 DeviceTypes.TYPE_CURTAIN to R.drawable.ic_device_blinds, 161 DeviceTypes.TYPE_DOOR to R.drawable.ic_device_door, 162 DeviceTypes.TYPE_SHUTTER to R.drawable.ic_device_window, 163 DeviceTypes.TYPE_HEATER to R.drawable.ic_device_thermostat, 164 RenderInfo.ERROR_ICON to R.drawable.ic_error_outline 165 ).withDefault { 166 R.drawable.ic_device_unknown 167 } 168