Merge "Controls UI - Persist subtitles" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-03-19 14:35:54 +00:00
committed by Android (Google) Code Review
11 changed files with 41 additions and 21 deletions

View File

@@ -71,6 +71,8 @@
android:paddingRight="@dimen/control_padding_adjustment" android:paddingRight="@dimen/control_padding_adjustment"
android:clickable="false" android:clickable="false"
android:focusable="false" android:focusable="false"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintBottom_toTopOf="@+id/subtitle" app:layout_constraintBottom_toTopOf="@+id/subtitle"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
@@ -84,6 +86,8 @@
android:paddingBottom="@dimen/control_padding_adjustment" android:paddingBottom="@dimen/control_padding_adjustment"
android:clickable="false" android:clickable="false"
android:focusable="false" android:focusable="false"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/> app:layout_constraintStart_toStartOf="parent"/>

View File

@@ -27,11 +27,13 @@ import android.service.controls.DeviceTypes
* *
* @property controlId unique identifier for this [Control]. * @property controlId unique identifier for this [Control].
* @property controlTitle last title reported for this [Control]. * @property controlTitle last title reported for this [Control].
* @property controlSubtitle last subtitle reported for this [Control].
* @property deviceType last reported type for this [Control]. * @property deviceType last reported type for this [Control].
*/ */
data class ControlInfo( data class ControlInfo(
val controlId: String, val controlId: String,
val controlTitle: CharSequence, val controlTitle: CharSequence,
val controlSubtitle: CharSequence,
@DeviceTypes.DeviceType val deviceType: Int @DeviceTypes.DeviceType val deviceType: Int
) { ) {
@@ -51,8 +53,9 @@ data class ControlInfo(
class Builder { class Builder {
lateinit var controlId: String lateinit var controlId: String
lateinit var controlTitle: CharSequence lateinit var controlTitle: CharSequence
lateinit var controlSubtitle: CharSequence
var deviceType: Int = DeviceTypes.TYPE_UNKNOWN var deviceType: Int = DeviceTypes.TYPE_UNKNOWN
fun build() = ControlInfo(controlId, controlTitle, deviceType) fun build() = ControlInfo(controlId, controlTitle, controlSubtitle, deviceType)
} }
} }

View File

@@ -327,8 +327,9 @@ class ControlsControllerImpl @Inject constructor (
controls.forEach { controls.forEach {
val structure = it.structure ?: "" val structure = it.structure ?: ""
val list = structureToControls.get(structure) val list = structureToControls.get(structure)
?: mutableListOf<ControlInfo>() ?: mutableListOf<ControlInfo>()
list.add(ControlInfo(it.controlId, it.title, it.deviceType)) list.add(
ControlInfo(it.controlId, it.title, it.subtitle, it.deviceType))
structureToControls.put(structure, list) structureToControls.put(structure, list)
} }
@@ -518,10 +519,12 @@ private object Favorites {
s.controls.forEach { c -> s.controls.forEach { c ->
val (sName, ci) = controlsById.get(c.controlId)?.let { updatedControl -> val (sName, ci) = controlsById.get(c.controlId)?.let { updatedControl ->
val controlInfo = if (updatedControl.title != c.controlTitle || val controlInfo = if (updatedControl.title != c.controlTitle ||
updatedControl.subtitle != c.controlSubtitle ||
updatedControl.deviceType != c.deviceType) { updatedControl.deviceType != c.deviceType) {
changed = true changed = true
c.copy( c.copy(
controlTitle = updatedControl.title, controlTitle = updatedControl.title,
controlSubtitle = updatedControl.subtitle,
deviceType = updatedControl.deviceType deviceType = updatedControl.deviceType
) )
} else { c } } else { c }

View File

@@ -51,6 +51,7 @@ class ControlsFavoritePersistenceWrapper(
private const val TAG_COMPONENT = "component" private const val TAG_COMPONENT = "component"
private const val TAG_ID = "id" private const val TAG_ID = "id"
private const val TAG_TITLE = "title" private const val TAG_TITLE = "title"
private const val TAG_SUBTITLE = "subtitle"
private const val TAG_TYPE = "type" private const val TAG_TYPE = "type"
private const val TAG_VERSION = "version" private const val TAG_VERSION = "version"
@@ -102,6 +103,7 @@ class ControlsFavoritePersistenceWrapper(
startTag(null, TAG_CONTROL) startTag(null, TAG_CONTROL)
attribute(null, TAG_ID, c.controlId) attribute(null, TAG_ID, c.controlId)
attribute(null, TAG_TITLE, c.controlTitle.toString()) attribute(null, TAG_TITLE, c.controlTitle.toString())
attribute(null, TAG_SUBTITLE, c.controlSubtitle.toString())
attribute(null, TAG_TYPE, c.deviceType.toString()) attribute(null, TAG_TYPE, c.deviceType.toString())
endTag(null, TAG_CONTROL) endTag(null, TAG_CONTROL)
} }
@@ -168,9 +170,10 @@ class ControlsFavoritePersistenceWrapper(
} else if (type == XmlPullParser.START_TAG && tagName == TAG_CONTROL) { } else if (type == XmlPullParser.START_TAG && tagName == TAG_CONTROL) {
val id = parser.getAttributeValue(null, TAG_ID) val id = parser.getAttributeValue(null, TAG_ID)
val title = parser.getAttributeValue(null, TAG_TITLE) val title = parser.getAttributeValue(null, TAG_TITLE)
val subtitle = parser.getAttributeValue(null, TAG_SUBTITLE) ?: ""
val deviceType = parser.getAttributeValue(null, TAG_TYPE)?.toInt() val deviceType = parser.getAttributeValue(null, TAG_TYPE)?.toInt()
if (id != null && title != null && deviceType != null) { if (id != null && title != null && deviceType != null) {
controls.add(ControlInfo(id, title, deviceType)) controls.add(ControlInfo(id, title, subtitle, deviceType))
} }
} else if (type == XmlPullParser.END_TAG && tagName == TAG_STRUCTURE) { } else if (type == XmlPullParser.END_TAG && tagName == TAG_STRUCTURE) {
infos.add(StructureInfo(lastComponent!!, lastStructure!!, controls.toList())) infos.add(StructureInfo(lastComponent!!, lastStructure!!, controls.toList()))

View File

@@ -51,6 +51,7 @@ class AllModel(
ControlInfo.Builder().apply { ControlInfo.Builder().apply {
controlId = it.controlId controlId = it.controlId
controlTitle = it.title controlTitle = it.title
controlSubtitle = it.subtitle
deviceType = it.deviceType deviceType = it.deviceType
} }
} }
@@ -120,4 +121,4 @@ class AllModel(
return removed return removed
} }
} }
} }

View File

@@ -169,8 +169,11 @@ class ControlsRequestDialog @Inject constructor(
override fun onClick(dialog: DialogInterface?, which: Int) { override fun onClick(dialog: DialogInterface?, which: Int) {
if (which == Dialog.BUTTON_POSITIVE) { if (which == Dialog.BUTTON_POSITIVE) {
controller.addFavorite(componentName, control.structure ?: "", controller.addFavorite(
ControlInfo(control.controlId, control.title, control.deviceType)) componentName,
control.structure ?: "",
ControlInfo(control.controlId, control.title, control.subtitle, control.deviceType)
)
} }
finish() finish()
} }

View File

@@ -77,7 +77,7 @@ class ControlViewHolder(
Pair(it.getStatus(), it.getControlTemplate()) Pair(it.getStatus(), it.getControlTemplate())
} ?: run { } ?: run {
title.setText(cws.ci.controlTitle) title.setText(cws.ci.controlTitle)
subtitle.setText("") subtitle.setText(cws.ci.controlSubtitle)
Pair(Control.STATUS_UNKNOWN, ControlTemplate.NO_TEMPLATE) Pair(Control.STATUS_UNKNOWN, ControlTemplate.NO_TEMPLATE)
} }

View File

@@ -266,8 +266,8 @@ class ControlsBindingControllerImplTest : SysuiTestCase() {
@Test @Test
fun testSubscribe() { fun testSubscribe() {
val controlInfo1 = ControlInfo("id_1", "", DeviceTypes.TYPE_UNKNOWN) val controlInfo1 = ControlInfo("id_1", "", "", DeviceTypes.TYPE_UNKNOWN)
val controlInfo2 = ControlInfo("id_2", "", DeviceTypes.TYPE_UNKNOWN) val controlInfo2 = ControlInfo("id_2", "", "", DeviceTypes.TYPE_UNKNOWN)
val structure = val structure =
StructureInfo(TEST_COMPONENT_NAME_1, "Home", listOf(controlInfo1, controlInfo2)) StructureInfo(TEST_COMPONENT_NAME_1, "Home", listOf(controlInfo1, controlInfo2))
@@ -296,8 +296,8 @@ class ControlsBindingControllerImplTest : SysuiTestCase() {
@Test @Test
fun testUnsubscribe_refreshing() { fun testUnsubscribe_refreshing() {
val controlInfo1 = ControlInfo("id_1", "", DeviceTypes.TYPE_UNKNOWN) val controlInfo1 = ControlInfo("id_1", "", "", DeviceTypes.TYPE_UNKNOWN)
val controlInfo2 = ControlInfo("id_2", "", DeviceTypes.TYPE_UNKNOWN) val controlInfo2 = ControlInfo("id_2", "", "", DeviceTypes.TYPE_UNKNOWN)
val structure = val structure =
StructureInfo(TEST_COMPONENT_NAME_1, "Home", listOf(controlInfo1, controlInfo2)) StructureInfo(TEST_COMPONENT_NAME_1, "Home", listOf(controlInfo1, controlInfo2))

View File

@@ -104,20 +104,22 @@ class ControlsControllerImplTest : SysuiTestCase() {
private val TEST_COMPONENT = ComponentName("test.pkg", "test.class") private val TEST_COMPONENT = ComponentName("test.pkg", "test.class")
private const val TEST_CONTROL_ID = "control1" private const val TEST_CONTROL_ID = "control1"
private const val TEST_CONTROL_TITLE = "Test" private const val TEST_CONTROL_TITLE = "Test"
private const val TEST_CONTROL_SUBTITLE = "TestSub"
private const val TEST_DEVICE_TYPE = DeviceTypes.TYPE_AC_HEATER private const val TEST_DEVICE_TYPE = DeviceTypes.TYPE_AC_HEATER
private const val TEST_STRUCTURE = "" private const val TEST_STRUCTURE = ""
private val TEST_CONTROL_INFO = ControlInfo(TEST_CONTROL_ID, private val TEST_CONTROL_INFO = ControlInfo(TEST_CONTROL_ID,
TEST_CONTROL_TITLE, TEST_DEVICE_TYPE) TEST_CONTROL_TITLE, TEST_CONTROL_SUBTITLE, TEST_DEVICE_TYPE)
private val TEST_STRUCTURE_INFO = StructureInfo(TEST_COMPONENT, private val TEST_STRUCTURE_INFO = StructureInfo(TEST_COMPONENT,
TEST_STRUCTURE, listOf(TEST_CONTROL_INFO)) TEST_STRUCTURE, listOf(TEST_CONTROL_INFO))
private val TEST_COMPONENT_2 = ComponentName("test.pkg", "test.class.2") private val TEST_COMPONENT_2 = ComponentName("test.pkg", "test.class.2")
private const val TEST_CONTROL_ID_2 = "control2" private const val TEST_CONTROL_ID_2 = "control2"
private const val TEST_CONTROL_TITLE_2 = "Test 2" private const val TEST_CONTROL_TITLE_2 = "Test 2"
private const val TEST_CONTROL_SUBTITLE_2 = "TestSub 2"
private const val TEST_DEVICE_TYPE_2 = DeviceTypes.TYPE_CAMERA private const val TEST_DEVICE_TYPE_2 = DeviceTypes.TYPE_CAMERA
private const val TEST_STRUCTURE_2 = "My House" private const val TEST_STRUCTURE_2 = "My House"
private val TEST_CONTROL_INFO_2 = ControlInfo(TEST_CONTROL_ID_2, private val TEST_CONTROL_INFO_2 = ControlInfo(TEST_CONTROL_ID_2,
TEST_CONTROL_TITLE_2, TEST_DEVICE_TYPE_2) TEST_CONTROL_TITLE_2, TEST_CONTROL_SUBTITLE_2, TEST_DEVICE_TYPE_2)
private val TEST_STRUCTURE_INFO_2 = StructureInfo(TEST_COMPONENT_2, private val TEST_STRUCTURE_INFO_2 = StructureInfo(TEST_COMPONENT_2,
TEST_STRUCTURE_2, listOf(TEST_CONTROL_INFO_2)) TEST_STRUCTURE_2, listOf(TEST_CONTROL_INFO_2))
} }
@@ -165,7 +167,7 @@ class ControlsControllerImplTest : SysuiTestCase() {
): Control.StatelessBuilder { ): Control.StatelessBuilder {
return Control.StatelessBuilder(controlInfo.controlId, pendingIntent) return Control.StatelessBuilder(controlInfo.controlId, pendingIntent)
.setDeviceType(controlInfo.deviceType).setTitle(controlInfo.controlTitle) .setDeviceType(controlInfo.deviceType).setTitle(controlInfo.controlTitle)
.setStructure(structure) .setSubtitle(controlInfo.controlSubtitle).setStructure(structure)
} }
@Test @Test
@@ -585,7 +587,7 @@ class ControlsControllerImplTest : SysuiTestCase() {
@Test @Test
fun testGetFavoritesForComponent_multipleInOrder() { fun testGetFavoritesForComponent_multipleInOrder() {
val controlInfo = ControlInfo("id", "title", 0) val controlInfo = ControlInfo("id", "title", "subtitle", 0)
controller.replaceFavoritesForStructure( controller.replaceFavoritesForStructure(
StructureInfo( StructureInfo(
@@ -643,7 +645,7 @@ class ControlsControllerImplTest : SysuiTestCase() {
@Test @Test
fun testReplaceFavoritesForStructure_oldFavoritesRemoved() { fun testReplaceFavoritesForStructure_oldFavoritesRemoved() {
val controlInfo = ControlInfo("id", "title", 0) val controlInfo = ControlInfo("id", "title", "subtitle", 0)
assertNotEquals(TEST_CONTROL_INFO, controlInfo) assertNotEquals(TEST_CONTROL_INFO, controlInfo)
val newComponent = ComponentName("test.pkg", "test.class.3") val newComponent = ComponentName("test.pkg", "test.class.3")
@@ -669,7 +671,7 @@ class ControlsControllerImplTest : SysuiTestCase() {
@Test @Test
fun testReplaceFavoritesForStructure_favoritesInOrder() { fun testReplaceFavoritesForStructure_favoritesInOrder() {
val controlInfo = ControlInfo("id", "title", 0) val controlInfo = ControlInfo("id", "title", "subtitle", 0)
val listOrder1 = listOf(TEST_CONTROL_INFO, controlInfo) val listOrder1 = listOf(TEST_CONTROL_INFO, controlInfo)
val structure1 = StructureInfo(TEST_COMPONENT, "Home", listOrder1) val structure1 = StructureInfo(TEST_COMPONENT, "Home", listOrder1)

View File

@@ -59,7 +59,7 @@ class ControlsFavoritePersistenceWrapperTest : SysuiTestCase() {
ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS_1")!!, ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS_1")!!,
"", "",
listOf( listOf(
ControlInfo("id1", "name_1", DeviceTypes.TYPE_UNKNOWN) ControlInfo("id1", "name_1", "", DeviceTypes.TYPE_UNKNOWN)
) )
) )
@@ -67,8 +67,8 @@ class ControlsFavoritePersistenceWrapperTest : SysuiTestCase() {
ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS_2")!!, ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS_2")!!,
"structure1", "structure1",
listOf( listOf(
ControlInfo("id2", "name_2", DeviceTypes.TYPE_GENERIC_ON_OFF), ControlInfo("id2", "name_2", "sub2", DeviceTypes.TYPE_GENERIC_ON_OFF),
ControlInfo("id3", "name_3", DeviceTypes.TYPE_GENERIC_ON_OFF) ControlInfo("id3", "name_3", "sub3", DeviceTypes.TYPE_GENERIC_ON_OFF)
) )
) )
val list = listOf(structureInfo1, structureInfo2) val list = listOf(structureInfo1, structureInfo2)

View File

@@ -116,6 +116,7 @@ class AllModelTest : SysuiTestCase() {
private fun sameControl(controlInfo: ControlInfo.Builder, control: Control): Boolean { private fun sameControl(controlInfo: ControlInfo.Builder, control: Control): Boolean {
return controlInfo.controlId == control.controlId && return controlInfo.controlId == control.controlId &&
controlInfo.controlTitle == control.title && controlInfo.controlTitle == control.title &&
controlInfo.controlSubtitle == control.subtitle &&
controlInfo.deviceType == control.deviceType controlInfo.deviceType == control.deviceType
} }