Controls UI - Support thumbnail template

Allow the background image to be changed. Use the i18n 'Loading...'
text.

Bug: 148207527
Test: manual, home mock apk for camera
Change-Id: I705648c948aaf34ab624ded4fdbef415791c2481
This commit is contained in:
Matt Pietal
2020-02-14 09:14:43 -05:00
parent 4bfcfe795f
commit 5bdfba4755
6 changed files with 133 additions and 8 deletions

View File

@@ -3902,4 +3902,6 @@
<!-- Whether to expand the lock screen user switcher by default -->
<java-symbol type="bool" name="config_expandLockScreenUserSwitcher" />
<java-symbol type="string" name="loading" />
</resources>

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)
}
}

View File

@@ -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))
}
}
}
}
}

View File

@@ -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))
}