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(icon!!.constantState.newDrawable(context.resources), fg, bg) 71 } 72 73 fun registerComponentIcon(componentName: ComponentName, icon: Drawable) { 74 appIconMap.put(componentName, icon) 75 } 76 77 fun clearCache() { 78 iconMap.clear() 79 appIconMap.clear() 80 } 81 } 82 } 83 84 private const val BUCKET_SIZE = 1000 85 private const val THERMOSTAT_RANGE = DeviceTypes.TYPE_THERMOSTAT * BUCKET_SIZE 86 87 private val deviceColorMap = mapOf<Int, Pair<Int, Int>>( 88 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_OFF) to 89 Pair(R.color.control_default_foreground, R.color.control_default_background), 90 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to 91 Pair(R.color.thermo_heat_foreground, R.color.control_enabled_thermo_heat_background), 92 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to 93 Pair(R.color.thermo_cool_foreground, R.color.control_enabled_thermo_cool_background), 94 DeviceTypes.TYPE_LIGHT 95 to Pair(R.color.light_foreground, R.color.control_enabled_light_background), 96 DeviceTypes.TYPE_CAMERA 97 to Pair(R.color.camera_foreground, R.color.control_enabled_default_background) 98 ).withDefault { 99 Pair(R.color.control_foreground, R.color.control_enabled_default_background) 100 } 101 102 private val deviceIconMap = mapOf<Int, Int>( 103 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_OFF) to 104 R.drawable.ic_device_thermostat_off, 105 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT) to 106 R.drawable.ic_device_thermostat, 107 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_COOL) to 108 R.drawable.ic_device_thermostat, 109 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_HEAT_COOL) to 110 R.drawable.ic_device_thermostat, 111 (THERMOSTAT_RANGE + TemperatureControlTemplate.MODE_ECO) to 112 R.drawable.ic_device_thermostat_off, 113 DeviceTypes.TYPE_THERMOSTAT to R.drawable.ic_device_thermostat, 114 DeviceTypes.TYPE_LIGHT to R.drawable.ic_device_light, 115 DeviceTypes.TYPE_CAMERA to R.drawable.ic_device_camera, 116 DeviceTypes.TYPE_LOCK to R.drawable.ic_device_lock, 117 DeviceTypes.TYPE_SWITCH to R.drawable.ic_device_switch, 118 DeviceTypes.TYPE_OUTLET to R.drawable.ic_device_outlet, 119 DeviceTypes.TYPE_VACUUM to R.drawable.ic_device_vacuum, 120 DeviceTypes.TYPE_MOP to R.drawable.ic_device_mop, 121 DeviceTypes.TYPE_AIR_FRESHENER to R.drawable.ic_device_air_freshener, 122 DeviceTypes.TYPE_AIR_PURIFIER to R.drawable.ic_device_air_purifier, 123 DeviceTypes.TYPE_FAN to R.drawable.ic_device_fan, 124 DeviceTypes.TYPE_HOOD to R.drawable.ic_device_hood, 125 DeviceTypes.TYPE_KETTLE to R.drawable.ic_device_kettle, 126 DeviceTypes.TYPE_MICROWAVE to R.drawable.ic_device_microwave, 127 DeviceTypes.TYPE_REMOTE_CONTROL to R.drawable.ic_device_remote_control, 128 DeviceTypes.TYPE_SET_TOP to R.drawable.ic_device_set_top, 129 DeviceTypes.TYPE_STYLER to R.drawable.ic_device_styler, 130 DeviceTypes.TYPE_TV to R.drawable.ic_device_tv, 131 DeviceTypes.TYPE_WATER_HEATER to R.drawable.ic_device_water_heater, 132 DeviceTypes.TYPE_DISHWASHER to R.drawable.ic_device_dishwasher, 133 DeviceTypes.TYPE_MULTICOOKER to R.drawable.ic_device_multicooker, 134 DeviceTypes.TYPE_SPRINKLER to R.drawable.ic_device_sprinkler, 135 DeviceTypes.TYPE_WASHER to R.drawable.ic_device_washer, 136 DeviceTypes.TYPE_BLINDS to R.drawable.ic_device_blinds, 137 DeviceTypes.TYPE_DRAWER to R.drawable.ic_device_drawer, 138 DeviceTypes.TYPE_GARAGE to R.drawable.ic_device_garage, 139 DeviceTypes.TYPE_GATE to R.drawable.ic_device_gate, 140 DeviceTypes.TYPE_PERGOLA to R.drawable.ic_device_pergola, 141 DeviceTypes.TYPE_WINDOW to R.drawable.ic_device_window, 142 DeviceTypes.TYPE_VALVE to R.drawable.ic_device_valve, 143 DeviceTypes.TYPE_SECURITY_SYSTEM to R.drawable.ic_device_security_system, 144 DeviceTypes.TYPE_REFRIGERATOR to R.drawable.ic_device_refrigerator, 145 DeviceTypes.TYPE_DOORBELL to R.drawable.ic_device_doorbell, 146 DeviceTypes.TYPE_ROUTINE to RenderInfo.APP_ICON_ID, 147 DeviceTypes.TYPE_AC_HEATER to R.drawable.ic_device_thermostat, 148 DeviceTypes.TYPE_AC_UNIT to R.drawable.ic_device_thermostat, 149 DeviceTypes.TYPE_COFFEE_MAKER to R.drawable.ic_device_kettle, 150 DeviceTypes.TYPE_DEHUMIDIFIER to R.drawable.ic_device_air_freshener, 151 DeviceTypes.TYPE_RADIATOR to R.drawable.ic_device_thermostat, 152 DeviceTypes.TYPE_STANDMIXER to R.drawable.ic_device_cooking, 153 DeviceTypes.TYPE_DISPLAY to R.drawable.ic_device_display, 154 DeviceTypes.TYPE_DRYER to R.drawable.ic_device_washer, 155 DeviceTypes.TYPE_MOWER to R.drawable.ic_device_outdoor_garden, 156 DeviceTypes.TYPE_SHOWER to R.drawable.ic_device_water, 157 DeviceTypes.TYPE_AWNING to R.drawable.ic_device_pergola, 158 DeviceTypes.TYPE_CLOSET to R.drawable.ic_device_drawer, 159 DeviceTypes.TYPE_CURTAIN to R.drawable.ic_device_blinds, 160 DeviceTypes.TYPE_DOOR to R.drawable.ic_device_door, 161 DeviceTypes.TYPE_SHUTTER to R.drawable.ic_device_window, 162 DeviceTypes.TYPE_HEATER to R.drawable.ic_device_thermostat, 163 RenderInfo.ERROR_ICON to R.drawable.ic_error_outline 164 ).withDefault { 165 R.drawable.ic_device_unknown 166 } 167