Controls UI - Stateless controls
Add support for touchable controls without any state. Refactor to support using app icons as well as device type specific icons. Cache icons since they will most likely be used many times. Bug: 150849751 Test: visual Change-Id: I2d729ced2361e623d3f575149b5c0b4492072ff3
This commit is contained in:
@@ -16,10 +16,12 @@
|
||||
|
||||
package com.android.systemui.controls
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.service.controls.Control
|
||||
|
||||
data class ControlStatus(
|
||||
val control: Control,
|
||||
val component: ComponentName,
|
||||
var favorite: Boolean,
|
||||
val removed: Boolean = false
|
||||
)
|
||||
)
|
||||
|
||||
@@ -238,7 +238,11 @@ class ControlsControllerImpl @Inject constructor (
|
||||
}
|
||||
val removed = findRemoved(favoritesForComponentKeys.toSet(), controls)
|
||||
val controlsWithFavorite = controls.map {
|
||||
ControlStatus(it, it.controlId in favoritesForComponentKeys)
|
||||
ControlStatus(
|
||||
it,
|
||||
componentName,
|
||||
it.controlId in favoritesForComponentKeys
|
||||
)
|
||||
}
|
||||
val loadData = createLoadDataObject(
|
||||
Favorites.getControlsForComponent(componentName)
|
||||
@@ -290,7 +294,7 @@ class ControlsControllerImpl @Inject constructor (
|
||||
.setTitle(controlInfo.controlTitle)
|
||||
.setDeviceType(controlInfo.deviceType)
|
||||
.build()
|
||||
return ControlStatus(control, true, setRemoved)
|
||||
return ControlStatus(control, componentName, true, setRemoved)
|
||||
}
|
||||
|
||||
private fun findRemoved(favoriteKeys: Set<String>, list: List<Control>): Set<String> {
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.android.systemui.controls.management
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.Icon
|
||||
import android.service.controls.DeviceTypes
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@@ -147,7 +147,7 @@ private class ControlHolder(view: View, val favoriteCallback: ModelFavoriteChang
|
||||
override fun bindData(wrapper: ElementWrapper) {
|
||||
wrapper as ControlWrapper
|
||||
val data = wrapper.controlStatus
|
||||
val renderInfo = getRenderInfo(data.control.deviceType)
|
||||
val renderInfo = getRenderInfo(data.component, data.control.deviceType)
|
||||
title.text = data.control.title
|
||||
subtitle.text = data.control.subtitle
|
||||
favorite.isChecked = data.favorite
|
||||
@@ -160,16 +160,17 @@ private class ControlHolder(view: View, val favoriteCallback: ModelFavoriteChang
|
||||
}
|
||||
|
||||
private fun getRenderInfo(
|
||||
component: ComponentName,
|
||||
@DeviceTypes.DeviceType deviceType: Int
|
||||
): RenderInfo {
|
||||
return RenderInfo.lookup(deviceType, true)
|
||||
return RenderInfo.lookup(itemView.context, component, deviceType, true)
|
||||
}
|
||||
|
||||
private fun applyRenderInfo(ri: RenderInfo) {
|
||||
val context = itemView.context
|
||||
val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme())
|
||||
|
||||
icon.setImageIcon(Icon.createWithResource(context, ri.iconResourceId))
|
||||
icon.setImageDrawable(ri.icon)
|
||||
icon.setImageTintList(fg)
|
||||
}
|
||||
}
|
||||
@@ -191,4 +192,4 @@ class MarginItemDecorator(
|
||||
right = sideMargins
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.app.Dialog
|
||||
import android.content.ComponentName
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Bundle
|
||||
import android.os.UserHandle
|
||||
import android.service.controls.Control
|
||||
@@ -137,11 +136,10 @@ class ControlsRequestDialog @Inject constructor(
|
||||
}
|
||||
|
||||
fun createDialog(label: CharSequence): Dialog {
|
||||
|
||||
val renderInfo = RenderInfo.lookup(control.deviceType, true)
|
||||
val renderInfo = RenderInfo.lookup(this, component, control.deviceType, true)
|
||||
val frame = LayoutInflater.from(this).inflate(R.layout.controls_dialog, null).apply {
|
||||
requireViewById<ImageView>(R.id.icon).apply {
|
||||
setImageIcon(Icon.createWithResource(context, renderInfo.iconResourceId))
|
||||
setImageDrawable(renderInfo.icon)
|
||||
setImageTintList(
|
||||
context.resources.getColorStateList(renderInfo.foreground, context.theme))
|
||||
}
|
||||
@@ -176,4 +174,4 @@ class ControlsRequestDialog @Inject constructor(
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import android.provider.Settings
|
||||
import android.service.controls.actions.BooleanAction
|
||||
import android.service.controls.actions.CommandAction
|
||||
import android.util.Log
|
||||
import android.view.HapticFeedbackConstants
|
||||
|
||||
@@ -36,6 +37,10 @@ object ControlActionCoordinator {
|
||||
cvh.clipLayer.setLevel(nextLevel)
|
||||
}
|
||||
|
||||
fun touch(cvh: ControlViewHolder, templateId: String) {
|
||||
cvh.action(CommandAction(templateId))
|
||||
}
|
||||
|
||||
fun longPress(cvh: ControlViewHolder) {
|
||||
// Long press snould only be called when there is valid control state, otherwise ignore
|
||||
cvh.cws.control?.let {
|
||||
|
||||
@@ -19,11 +19,11 @@ package com.android.systemui.controls.ui
|
||||
import android.content.Context
|
||||
import android.graphics.BlendMode
|
||||
import android.graphics.drawable.ClipDrawable
|
||||
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.StatelessTemplate
|
||||
import android.service.controls.templates.TemperatureControlTemplate
|
||||
import android.service.controls.templates.ToggleRangeTemplate
|
||||
import android.service.controls.templates.ToggleTemplate
|
||||
@@ -122,19 +122,25 @@ class ControlViewHolder(
|
||||
return when {
|
||||
status == Control.STATUS_UNKNOWN -> UnknownBehavior::class
|
||||
template is ToggleTemplate -> ToggleBehavior::class
|
||||
template is StatelessTemplate -> TouchBehavior::class
|
||||
template is ToggleRangeTemplate -> ToggleRangeBehavior::class
|
||||
template is TemperatureControlTemplate -> TemperatureControlBehavior::class
|
||||
else -> DefaultBehavior::class
|
||||
}
|
||||
}
|
||||
|
||||
internal fun applyRenderInfo(ri: RenderInfo) {
|
||||
internal fun applyRenderInfo(enabled: Boolean, offset: Int = 0) {
|
||||
setEnabled(enabled)
|
||||
|
||||
val deviceType = cws.control?.let { it.getDeviceType() } ?: cws.ci.deviceType
|
||||
val ri = RenderInfo.lookup(context, cws.componentName, deviceType, enabled, offset)
|
||||
|
||||
val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme())
|
||||
val bg = context.getResources().getColorStateList(ri.background, context.getTheme())
|
||||
status.setTextColor(fg)
|
||||
statusExtra.setTextColor(fg)
|
||||
|
||||
icon.setImageIcon(Icon.createWithResource(context, ri.iconResourceId))
|
||||
icon.setImageDrawable(ri.icon)
|
||||
icon.setImageTintList(fg)
|
||||
|
||||
clipLayer.getDrawable().apply {
|
||||
@@ -143,7 +149,7 @@ class ControlViewHolder(
|
||||
}
|
||||
}
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
private fun setEnabled(enabled: Boolean) {
|
||||
status.setEnabled(enabled)
|
||||
icon.setEnabled(enabled)
|
||||
}
|
||||
|
||||
@@ -188,36 +188,23 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
parent.removeAllViews()
|
||||
controlViewsById.clear()
|
||||
|
||||
val inflater = LayoutInflater.from(context)
|
||||
inflater.inflate(R.layout.controls_with_favorites, parent, true)
|
||||
createListView()
|
||||
createDropDown(items)
|
||||
}
|
||||
|
||||
val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
|
||||
var lastRow: ViewGroup = createRow(inflater, listView)
|
||||
selectedStructure.controls.forEach {
|
||||
if (lastRow.getChildCount() == 2) {
|
||||
lastRow = createRow(inflater, listView)
|
||||
}
|
||||
val item = inflater.inflate(
|
||||
R.layout.controls_base_item, lastRow, false) as ViewGroup
|
||||
lastRow.addView(item)
|
||||
val cvh = ControlViewHolder(item, controlsController.get(), uiExecutor, bgExecutor)
|
||||
val key = ControlKey(selectedStructure.componentName, it.controlId)
|
||||
cvh.bindData(controlsById.getValue(key))
|
||||
controlViewsById.put(key, cvh)
|
||||
}
|
||||
|
||||
// add spacer if necessary to keep control size consistent
|
||||
if ((selectedStructure.controls.size % 2) == 1) {
|
||||
lastRow.addView(Space(context), LinearLayout.LayoutParams(0, 0, 1f))
|
||||
private fun createDropDown(items: List<SelectionItem>) {
|
||||
items.forEach {
|
||||
RenderInfo.registerComponentIcon(it.componentName, it.icon)
|
||||
}
|
||||
|
||||
val itemsByComponent = items.associateBy { it.componentName }
|
||||
var adapter = ItemAdapter(context, R.layout.controls_spinner_item).apply {
|
||||
val listItems = allStructures.mapNotNull {
|
||||
itemsByComponent.get(it.componentName)?.copy(structure = it.structure)
|
||||
}
|
||||
val itemsWithStructure = allStructures.mapNotNull {
|
||||
itemsByComponent.get(it.componentName)?.copy(structure = it.structure)
|
||||
}
|
||||
val selectionItem = findSelectionItem(selectedStructure, itemsWithStructure) ?: items[0]
|
||||
|
||||
addAll(listItems + addControlsItem)
|
||||
var adapter = ItemAdapter(context, R.layout.controls_spinner_item).apply {
|
||||
addAll(itemsWithStructure + addControlsItem)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -225,16 +212,15 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
* for this dialog. Use a textView with the ListPopupWindow to achieve
|
||||
* a similar effect
|
||||
*/
|
||||
val item = adapter.findSelectionItem(selectedStructure) ?: adapter.getItem(0)
|
||||
parent.requireViewById<TextView>(R.id.app_or_structure_spinner).apply {
|
||||
setText(item.getTitle())
|
||||
setText(selectionItem.getTitle())
|
||||
// override the default color on the dropdown drawable
|
||||
(getBackground() as LayerDrawable).getDrawable(1)
|
||||
.setTint(context.resources.getColor(R.color.control_spinner_dropdown, null))
|
||||
}
|
||||
parent.requireViewById<ImageView>(R.id.app_icon).apply {
|
||||
setContentDescription(item.getTitle())
|
||||
setImageDrawable(item.icon)
|
||||
setContentDescription(selectionItem.getTitle())
|
||||
setImageDrawable(selectionItem.icon)
|
||||
}
|
||||
val anchor = parent.requireViewById<ViewGroup>(R.id.controls_header)
|
||||
anchor.setOnClickListener(object : View.OnClickListener {
|
||||
@@ -272,6 +258,36 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
})
|
||||
}
|
||||
|
||||
private fun createListView() {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
inflater.inflate(R.layout.controls_with_favorites, parent, true)
|
||||
|
||||
val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
|
||||
var lastRow: ViewGroup = createRow(inflater, listView)
|
||||
selectedStructure.controls.forEach {
|
||||
if (lastRow.getChildCount() == 2) {
|
||||
lastRow = createRow(inflater, listView)
|
||||
}
|
||||
val baseLayout = inflater.inflate(
|
||||
R.layout.controls_base_item, lastRow, false) as ViewGroup
|
||||
lastRow.addView(baseLayout)
|
||||
val cvh = ControlViewHolder(
|
||||
baseLayout,
|
||||
controlsController.get(),
|
||||
uiExecutor,
|
||||
bgExecutor
|
||||
)
|
||||
val key = ControlKey(selectedStructure.componentName, it.controlId)
|
||||
cvh.bindData(controlsById.getValue(key))
|
||||
controlViewsById.put(key, cvh)
|
||||
}
|
||||
|
||||
// add spacer if necessary to keep control size consistent
|
||||
if ((selectedStructure.controls.size % 2) == 1) {
|
||||
lastRow.addView(Space(context), LinearLayout.LayoutParams(0, 0, 1f))
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadPreference(structures: List<StructureInfo>): StructureInfo {
|
||||
if (structures.isEmpty()) return EMPTY_STRUCTURE
|
||||
|
||||
@@ -320,6 +336,8 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
controlsById.clear()
|
||||
controlViewsById.clear()
|
||||
controlsListingController.get().removeCallback(listingCallback)
|
||||
|
||||
RenderInfo.clearCache()
|
||||
}
|
||||
|
||||
override fun onRefreshState(componentName: ComponentName, controls: List<Control>) {
|
||||
@@ -358,6 +376,11 @@ class ControlsUiControllerImpl @Inject constructor (
|
||||
listView.addView(row)
|
||||
return row
|
||||
}
|
||||
|
||||
private fun findSelectionItem(si: StructureInfo, items: List<SelectionItem>): SelectionItem? =
|
||||
items.firstOrNull {
|
||||
it.componentName == si.componentName && it.structure == si.structure
|
||||
}
|
||||
}
|
||||
|
||||
private data class SelectionItem(
|
||||
@@ -388,17 +411,4 @@ private class ItemAdapter(
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
fun findSelectionItem(si: StructureInfo): SelectionItem? {
|
||||
var i = 0
|
||||
while (i < getCount()) {
|
||||
val item = getItem(i)
|
||||
if (item.componentName == si.componentName &&
|
||||
item.structure == si.structure) {
|
||||
return item
|
||||
}
|
||||
i++
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ class DefaultBehavior : Behavior {
|
||||
|
||||
override fun bind(cws: ControlWithState) {
|
||||
cvh.status.setText(cws.control?.getStatusText() ?: "")
|
||||
cvh.setEnabled(false)
|
||||
cvh.applyRenderInfo(RenderInfo.lookup(cws.ci.deviceType, false))
|
||||
cvh.applyRenderInfo(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,14 @@
|
||||
|
||||
package com.android.systemui.controls.ui
|
||||
|
||||
import android.annotation.MainThread
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.service.controls.DeviceTypes
|
||||
import android.service.controls.templates.TemperatureControlTemplate
|
||||
import android.util.ArrayMap
|
||||
import android.util.SparseArray
|
||||
|
||||
import com.android.systemui.R
|
||||
|
||||
@@ -31,18 +37,54 @@ data class IconState(val disabledResourceId: Int, val enabledResourceId: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
data class RenderInfo(val iconResourceId: Int, val foreground: Int, val background: Int) {
|
||||
data class RenderInfo(val icon: Drawable, val foreground: Int, val background: Int) {
|
||||
|
||||
companion object {
|
||||
fun lookup(deviceType: Int, enabled: Boolean): RenderInfo {
|
||||
val iconState = deviceIconMap.getValue(deviceType)
|
||||
const val APP_ICON_ID = -1
|
||||
private val iconMap = SparseArray<Drawable>()
|
||||
private val appIconMap = ArrayMap<ComponentName, Drawable>()
|
||||
|
||||
@MainThread
|
||||
fun lookup(
|
||||
context: Context,
|
||||
componentName: ComponentName,
|
||||
deviceType: Int,
|
||||
enabled: Boolean,
|
||||
offset: Int = 0
|
||||
): RenderInfo {
|
||||
val (fg, bg) = deviceColorMap.getValue(deviceType)
|
||||
return RenderInfo(iconState[enabled], fg, bg)
|
||||
|
||||
val iconKey = if (offset > 0) {
|
||||
deviceType * BUCKET_SIZE + offset
|
||||
} else deviceType
|
||||
|
||||
val iconState = deviceIconMap.getValue(iconKey)
|
||||
val resourceId = iconState[enabled]
|
||||
var icon: Drawable? = null
|
||||
if (resourceId == APP_ICON_ID) {
|
||||
icon = appIconMap.get(componentName)
|
||||
if (icon == null) {
|
||||
icon = context.resources
|
||||
.getDrawable(R.drawable.ic_device_unknown_gm2_24px, null)
|
||||
appIconMap.put(componentName, icon)
|
||||
}
|
||||
} else {
|
||||
icon = iconMap.get(resourceId)
|
||||
if (icon == null) {
|
||||
icon = context.resources.getDrawable(resourceId, null)
|
||||
iconMap.put(resourceId, icon)
|
||||
}
|
||||
}
|
||||
return RenderInfo(icon!!, fg, bg)
|
||||
}
|
||||
|
||||
fun lookup(deviceType: Int, offset: Int, enabled: Boolean): RenderInfo {
|
||||
val key = deviceType * BUCKET_SIZE + offset
|
||||
return lookup(key, enabled)
|
||||
fun registerComponentIcon(componentName: ComponentName, icon: Drawable) {
|
||||
appIconMap.put(componentName, icon)
|
||||
}
|
||||
|
||||
fun clearCache() {
|
||||
iconMap.clear()
|
||||
appIconMap.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,6 +158,10 @@ private val deviceIconMap = mapOf<Int, IconState>(
|
||||
DeviceTypes.TYPE_MOP to IconState(
|
||||
R.drawable.ic_vacuum_gm2_24px,
|
||||
R.drawable.ic_vacuum_gm2_24px
|
||||
),
|
||||
DeviceTypes.TYPE_ROUTINE to IconState(
|
||||
RenderInfo.APP_ICON_ID,
|
||||
RenderInfo.APP_ICON_ID
|
||||
)
|
||||
).withDefault {
|
||||
IconState(
|
||||
|
||||
@@ -47,10 +47,7 @@ class TemperatureControlBehavior : Behavior {
|
||||
|
||||
val activeMode = template.getCurrentActiveMode()
|
||||
val enabled = activeMode != 0 && activeMode != TemperatureControlTemplate.MODE_OFF
|
||||
val deviceType = control.getDeviceType()
|
||||
|
||||
clipLayer.setLevel(if (enabled) MAX_LEVEL else MIN_LEVEL)
|
||||
cvh.setEnabled(enabled)
|
||||
cvh.applyRenderInfo(RenderInfo.lookup(deviceType, activeMode, enabled))
|
||||
cvh.applyRenderInfo(enabled, activeMode)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class ToggleBehavior : Behavior {
|
||||
|
||||
override fun initialize(cvh: ControlViewHolder) {
|
||||
this.cvh = cvh
|
||||
cvh.setEnabled(false)
|
||||
cvh.applyRenderInfo(false)
|
||||
|
||||
cvh.layout.setOnClickListener(View.OnClickListener() {
|
||||
ControlActionCoordinator.toggle(cvh, template.getTemplateId(), template.isChecked())
|
||||
@@ -51,10 +51,7 @@ class ToggleBehavior : Behavior {
|
||||
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
|
||||
|
||||
val checked = template.isChecked()
|
||||
val deviceType = control.getDeviceType()
|
||||
|
||||
clipLayer.setLevel(if (checked) MAX_LEVEL else MIN_LEVEL)
|
||||
cvh.setEnabled(checked)
|
||||
cvh.applyRenderInfo(RenderInfo.lookup(deviceType, checked))
|
||||
cvh.applyRenderInfo(checked)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class ToggleRangeBehavior : Behavior {
|
||||
status = cvh.status
|
||||
context = status.getContext()
|
||||
|
||||
cvh.setEnabled(false)
|
||||
cvh.applyRenderInfo(false)
|
||||
|
||||
val gestureListener = ToggleRangeGestureListener(cvh.layout)
|
||||
val gestureDetector = GestureDetector(context, gestureListener)
|
||||
@@ -89,14 +89,11 @@ class ToggleRangeBehavior : Behavior {
|
||||
rangeTemplate = template.getRange()
|
||||
|
||||
val checked = template.isChecked()
|
||||
val deviceType = control.getDeviceType()
|
||||
|
||||
val currentRatio = rangeTemplate.getCurrentValue() /
|
||||
(rangeTemplate.getMaxValue() - rangeTemplate.getMinValue())
|
||||
updateRange(currentRatio, checked)
|
||||
|
||||
cvh.setEnabled(checked)
|
||||
cvh.applyRenderInfo(RenderInfo.lookup(deviceType, checked))
|
||||
cvh.applyRenderInfo(checked)
|
||||
}
|
||||
|
||||
fun beginUpdateRange() {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.Drawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.view.View
|
||||
import android.service.controls.Control
|
||||
import android.service.controls.templates.StatelessTemplate
|
||||
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.controls.ui.ControlActionCoordinator.MIN_LEVEL
|
||||
|
||||
/**
|
||||
* Supports touch events, but has no notion of state as the {@link ToggleBehavior} does. Must be
|
||||
* used with {@link StatelessTemplate}.
|
||||
*/
|
||||
class TouchBehavior : Behavior {
|
||||
lateinit var clipLayer: Drawable
|
||||
lateinit var template: StatelessTemplate
|
||||
lateinit var control: Control
|
||||
lateinit var cvh: ControlViewHolder
|
||||
|
||||
override fun initialize(cvh: ControlViewHolder) {
|
||||
this.cvh = cvh
|
||||
cvh.applyRenderInfo(false)
|
||||
|
||||
cvh.layout.setOnClickListener(View.OnClickListener() {
|
||||
ControlActionCoordinator.touch(cvh, template.getTemplateId())
|
||||
})
|
||||
}
|
||||
|
||||
override fun bind(cws: ControlWithState) {
|
||||
this.control = cws.control!!
|
||||
cvh.status.setText(control.getStatusText())
|
||||
template = control.getControlTemplate() as StatelessTemplate
|
||||
|
||||
val ld = cvh.layout.getBackground() as LayerDrawable
|
||||
clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
|
||||
clipLayer.setLevel(MIN_LEVEL)
|
||||
|
||||
cvh.applyRenderInfo(false)
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,6 @@ class UnknownBehavior : Behavior {
|
||||
|
||||
override fun bind(cws: ControlWithState) {
|
||||
cvh.status.setText(cvh.context.getString(com.android.internal.R.string.loading))
|
||||
cvh.setEnabled(false)
|
||||
cvh.applyRenderInfo(RenderInfo.lookup(cws.ci.deviceType, false))
|
||||
cvh.applyRenderInfo(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ class ControlsControllerImplTest : SysuiTestCase() {
|
||||
loaded = true
|
||||
assertEquals(1, controls.size)
|
||||
val controlStatus = controls[0]
|
||||
assertEquals(ControlStatus(control, false), controlStatus)
|
||||
assertEquals(ControlStatus(control, TEST_COMPONENT, false), controlStatus)
|
||||
|
||||
assertTrue(favorites.isEmpty())
|
||||
assertFalse(data.errorOnLoad)
|
||||
@@ -265,10 +265,10 @@ class ControlsControllerImplTest : SysuiTestCase() {
|
||||
loaded = true
|
||||
assertEquals(2, controls.size)
|
||||
val controlStatus = controls.first { it.control.controlId == TEST_CONTROL_ID }
|
||||
assertEquals(ControlStatus(control, true), controlStatus)
|
||||
assertEquals(ControlStatus(control, TEST_COMPONENT, true), controlStatus)
|
||||
|
||||
val controlStatus2 = controls.first { it.control.controlId == TEST_CONTROL_ID_2 }
|
||||
assertEquals(ControlStatus(control2, false), controlStatus2)
|
||||
assertEquals(ControlStatus(control2, TEST_COMPONENT, false), controlStatus2)
|
||||
|
||||
assertEquals(1, favorites.size)
|
||||
assertEquals(TEST_CONTROL_ID, favorites[0])
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.controls.management
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.ComponentName
|
||||
import android.service.controls.Control
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
@@ -78,6 +79,7 @@ class AllModelTest : SysuiTestCase() {
|
||||
Control.StatelessBuilder("$idPrefix$it", pendingIntent)
|
||||
.setZone(zoneMap(it))
|
||||
.build(),
|
||||
ComponentName("", ""),
|
||||
it in favoritesIndices
|
||||
)
|
||||
}
|
||||
@@ -189,4 +191,4 @@ class AllModelTest : SysuiTestCase() {
|
||||
assertTrue(sameControl(it.first, it.second))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.controls.management
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.ComponentName
|
||||
import android.service.controls.Control
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
@@ -70,6 +71,7 @@ open class FavoriteModelTest : SysuiTestCase() {
|
||||
Control.StatelessBuilder("$idPrefix$it", pendingIntent)
|
||||
.setZone((it % 3).toString())
|
||||
.build(),
|
||||
ComponentName("", ""),
|
||||
it in favoritesIndices
|
||||
)
|
||||
}
|
||||
@@ -195,4 +197,4 @@ class FavoriteModelParameterizedTest(val from: Int, val to: Int) : FavoriteModel
|
||||
|
||||
verifyNoMoreInteractions(allAdapter, favoritesAdapter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user