Merge "Controls UI - Fix icon, title, subtitle for error states" into rvc-dev
diff --git a/packages/SystemUI/res/drawable/ic_error_outline.xml b/packages/SystemUI/res/drawable/ic_error_outline.xml
new file mode 100644
index 0000000..140180a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_error_outline.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M11,15h2v2h-2v-2zM11,7h2v6h-2L11,7zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
+</vector>
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 9e7cf1a..353367e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -87,9 +87,7 @@
             deviceType: Int
         ): KClass<out Behavior> {
             return when {
-                status == Control.STATUS_UNKNOWN -> StatusBehavior::class
-                status == Control.STATUS_ERROR -> StatusBehavior::class
-                status == Control.STATUS_NOT_FOUND -> StatusBehavior::class
+                status != Control.STATUS_OK -> StatusBehavior::class
                 deviceType == DeviceTypes.TYPE_CAMERA -> TouchBehavior::class
                 template is ToggleTemplate -> ToggleBehavior::class
                 template is StatelessTemplate -> TouchBehavior::class
@@ -123,7 +121,11 @@
     private val onDialogCancel: () -> Unit = { lastChallengeDialog = null }
 
     val deviceType: Int
-        get() = cws.control?.let { it.getDeviceType() } ?: cws.ci.deviceType
+        get() = cws.control?.let { it.deviceType } ?: cws.ci.deviceType
+    val controlStatus: Int
+        get() = cws.control?.let { it.status } ?: Control.STATUS_UNKNOWN
+    val controlTemplate: ControlTemplate
+        get() = cws.control?.let { it.controlTemplate } ?: ControlTemplate.NO_TEMPLATE
 
     init {
         val ld = layout.getBackground() as LayerDrawable
@@ -140,14 +142,16 @@
 
         cancelUpdate?.run()
 
-        val (controlStatus, template) = cws.control?.let {
-            title.setText(it.getTitle())
-            subtitle.setText(it.getSubtitle())
-            Pair(it.status, it.controlTemplate)
-        } ?: run {
+        // For the following statuses only, assume the title/subtitle could not be set properly
+        // by the app and instead use the last known information from favorites
+        if (controlStatus == Control.STATUS_UNKNOWN || controlStatus == Control.STATUS_NOT_FOUND) {
             title.setText(cws.ci.controlTitle)
             subtitle.setText(cws.ci.controlSubtitle)
-            Pair(Control.STATUS_UNKNOWN, ControlTemplate.NO_TEMPLATE)
+        } else {
+            cws.control?.let {
+                title.setText(it.title)
+                subtitle.setText(it.subtitle)
+            }
         }
 
         cws.control?.let {
@@ -161,7 +165,8 @@
         }
 
         isLoading = false
-        behavior = bindBehavior(behavior, findBehaviorClass(controlStatus, template, deviceType))
+        behavior = bindBehavior(behavior,
+            findBehaviorClass(controlStatus, controlTemplate, deviceType))
         updateContentDescription()
     }
 
@@ -256,7 +261,13 @@
     }
 
     internal fun applyRenderInfo(enabled: Boolean, offset: Int, animated: Boolean = true) {
-        val ri = RenderInfo.lookup(context, cws.componentName, deviceType, offset)
+        val deviceTypeOrError = if (controlStatus == Control.STATUS_OK ||
+                controlStatus == Control.STATUS_UNKNOWN) {
+            deviceType
+        } else {
+            RenderInfo.ERROR_ICON
+        }
+        val ri = RenderInfo.lookup(context, cws.componentName, deviceTypeOrError, offset)
         val fg = context.resources.getColorStateList(ri.foreground, context.theme)
         val newText = nextStatusText
         nextStatusText = ""
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
index 09d41bd..3f17a4f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
@@ -35,6 +35,7 @@
 ) {
     companion object {
         const val APP_ICON_ID = -1
+        const val ERROR_ICON = -1000
         private val iconMap = SparseArray<Drawable>()
         private val appIconMap = ArrayMap<ComponentName, Drawable>()
 
@@ -156,7 +157,8 @@
     DeviceTypes.TYPE_CURTAIN to R.drawable.ic_device_blinds,
     DeviceTypes.TYPE_DOOR to R.drawable.ic_device_door,
     DeviceTypes.TYPE_SHUTTER to R.drawable.ic_device_window,
-    DeviceTypes.TYPE_HEATER to R.drawable.ic_device_thermostat
+    DeviceTypes.TYPE_HEATER to R.drawable.ic_device_thermostat,
+    RenderInfo.ERROR_ICON to R.drawable.ic_error_outline
 ).withDefault {
     R.drawable.ic_device_unknown
 }