Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5bdfba47 authored by Matt Pietal's avatar Matt Pietal
Browse files

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
parent 4bfcfe79
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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>
+7 −6
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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)
+57 −0
Original line number Diff line number Diff line
/*
 * 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)
    }
}
+65 −0
Original line number Diff line number Diff line
/*
 * 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))
                }
            }
        }
    }
}
Loading