diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5aefe11712463..b3dd1fc949b82 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3902,4 +3902,6 @@
+
+
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 55c1b6a1e369a..aec207518b9f1 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -17,14 +17,15 @@
package com.android.systemui.controls.ui
import android.content.Context
+import android.graphics.BlendMode
import android.graphics.drawable.ClipDrawable
-import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.Icon
import android.graphics.drawable.LayerDrawable
import android.service.controls.Control
import android.service.controls.actions.ControlAction
import android.service.controls.templates.ControlTemplate
import android.service.controls.templates.TemperatureControlTemplate
+import android.service.controls.templates.ThumbnailTemplate
import android.service.controls.templates.ToggleRangeTemplate
import android.service.controls.templates.ToggleTemplate
import android.view.View
@@ -41,7 +42,8 @@ private const val UPDATE_DELAY_IN_MILLIS = 3000L
class ControlViewHolder(
val layout: ViewGroup,
val controlsController: ControlsController,
- val uiExecutor: DelayableExecutor
+ val uiExecutor: DelayableExecutor,
+ val bgExecutor: DelayableExecutor
) {
val icon: ImageView = layout.requireViewById(R.id.icon)
val status: TextView = layout.requireViewById(R.id.status)
@@ -50,7 +52,6 @@ class ControlViewHolder(
val subtitle: TextView = layout.requireViewById(R.id.subtitle)
val context: Context = layout.getContext()
val clipLayer: ClipDrawable
- val gd: GradientDrawable
lateinit var cws: ControlWithState
var cancelUpdate: Runnable? = null
@@ -58,7 +59,6 @@ class ControlViewHolder(
val ld = layout.getBackground() as LayerDrawable
ld.mutate()
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) as ClipDrawable
- gd = clipLayer.getDrawable() as GradientDrawable
}
fun bindData(cws: ControlWithState) {
@@ -121,6 +121,7 @@ class ControlViewHolder(
template is ToggleTemplate -> ToggleBehavior()
template is ToggleRangeTemplate -> ToggleRangeBehavior()
template is TemperatureControlTemplate -> TemperatureControlBehavior()
+ template is ThumbnailTemplate -> StaticBehavior(uiExecutor, bgExecutor)
else -> {
object : Behavior {
override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
@@ -141,9 +142,9 @@ class ControlViewHolder(
icon.setImageIcon(Icon.createWithResource(context, ri.iconResourceId))
icon.setImageTintList(fg)
- gd.setColor(bg)
+ clipLayer.getDrawable().setTintBlendMode(BlendMode.HUE)
+ clipLayer.getDrawable().setTintList(bg)
}
-
fun setEnabled(enabled: Boolean) {
status.setEnabled(enabled)
icon.setEnabled(enabled)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 9e6636fca97d3..98cdf288f1a1f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -223,7 +223,7 @@ class ControlsUiControllerImpl @Inject constructor (
val item = inflater.inflate(
R.layout.controls_base_item, lastRow, false) as ViewGroup
lastRow.addView(item)
- val cvh = ControlViewHolder(item, controlsController.get(), uiExecutor)
+ val cvh = ControlViewHolder(item, controlsController.get(), uiExecutor, bgExecutor)
val key = ControlKey(it.component, it.controlId)
cvh.bindData(controlsById.getValue(key))
controlViewsById.put(key, cvh)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt
new file mode 100644
index 0000000000000..af581e1aa53b9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.controls.ui
+
+import android.graphics.Canvas
+import android.graphics.Path
+import android.graphics.Rect
+import android.graphics.RectF
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.DrawableWrapper
+
+/**
+ * Use a path to add mask for corners around the drawable, to match the radius
+ * of the underlying shape.
+ */
+class CornerDrawable(val wrapped: Drawable, val cornerRadius: Float) : DrawableWrapper(wrapped) {
+ val path: Path = Path()
+
+ init {
+ val b = getBounds()
+ updatePath(RectF(b))
+ }
+
+ override fun draw(canvas: Canvas) {
+ canvas.clipPath(path)
+ super.draw(canvas)
+ }
+
+ override fun setBounds(l: Int, t: Int, r: Int, b: Int) {
+ updatePath(RectF(l.toFloat(), t.toFloat(), r.toFloat(), b.toFloat()))
+ super.setBounds(l, t, r, b)
+ }
+
+ override fun setBounds(r: Rect) {
+ updatePath(RectF(r))
+ super.setBounds(r)
+ }
+
+ private fun updatePath(r: RectF) {
+ path.reset()
+ path.addRoundRect(r, cornerRadius, cornerRadius, Path.Direction.CW)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StaticBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StaticBehavior.kt
new file mode 100644
index 0000000000000..c69e45159ec89
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StaticBehavior.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.controls.ui
+
+import android.graphics.drawable.ClipDrawable
+import android.graphics.drawable.LayerDrawable
+import android.service.controls.Control
+import android.service.controls.templates.ThumbnailTemplate
+
+import com.android.systemui.R
+import com.android.systemui.controls.ui.ControlActionCoordinator.MAX_LEVEL
+
+import java.util.concurrent.Executor
+
+/**
+ * Used for controls that cannot be interacted with. Information is presented to the user
+ * but no actions can be taken. If using a ThumbnailTemplate, the background image will
+ * be changed.
+ */
+class StaticBehavior(
+ val uiExecutor: Executor,
+ val bgExecutor: Executor
+) : Behavior {
+ lateinit var control: Control
+
+ override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
+ this.control = cws.control!!
+
+ cvh.status.setText(control.getStatusText())
+
+ val ld = cvh.layout.getBackground() as LayerDrawable
+ val clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) as ClipDrawable
+
+ clipLayer.setLevel(MAX_LEVEL)
+ cvh.setEnabled(true)
+ cvh.applyRenderInfo(RenderInfo.lookup(control.getDeviceType(), true))
+
+ val template = control.getControlTemplate()
+ if (template is ThumbnailTemplate) {
+ bgExecutor.execute {
+ val drawable = template.getThumbnail().loadDrawable(cvh.context)
+ uiExecutor.execute {
+ val radius = cvh.context.getResources()
+ .getDimensionPixelSize(R.dimen.control_corner_radius).toFloat()
+ clipLayer.setDrawable(CornerDrawable(drawable, radius))
+ cvh.applyRenderInfo(RenderInfo.lookup(control.getDeviceType(), true))
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt
index 5a6e5b4815447..27f1b336e6b23 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/UnknownBehavior.kt
@@ -18,7 +18,7 @@ package com.android.systemui.controls.ui
class UnknownBehavior : Behavior {
override fun apply(cvh: ControlViewHolder, cws: ControlWithState) {
- cvh.status.setText("Loading...")
+ cvh.status.setText(cvh.context.getString(com.android.internal.R.string.loading))
cvh.setEnabled(false)
cvh.applyRenderInfo(RenderInfo.lookup(cws.ci.deviceType, false))
}