From e810130daf80818b2225cc81a378c29b867603c2 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Mon, 17 May 2021 15:28:59 +0000 Subject: [PATCH] [Device Controls] For custom icons, keep the tint the icon comes with. Test: atest (+ new unit tests) and manual (Google Home speaker tile icon should now be gray not white) Fixes: 181036023 Change-Id: I170867122a08bf22bcf7acf5eec7b9ebea20d9f5 --- .../systemui/controls/ui/ControlViewHolder.kt | 9 +- .../controls/ui/ControlViewHolderTest.kt | 118 ++++++++++++++++++ 2 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt 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 b15bb45b3c321..47e749cd11851 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt @@ -47,6 +47,7 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.annotation.ColorInt +import androidx.annotation.VisibleForTesting import com.android.internal.graphics.ColorUtils import com.android.systemui.R import com.android.systemui.animation.Interpolators @@ -454,7 +455,8 @@ class ControlViewHolder( } } - private fun updateStatusRow( + @VisibleForTesting + internal fun updateStatusRow( enabled: Boolean, text: CharSequence, drawable: Drawable, @@ -469,11 +471,8 @@ class ControlViewHolder( status.setTextColor(color) control?.getCustomIcon()?.let { - // do not tint custom icons, assume the intended icon color is correct - if (icon.imageTintList != null) { - icon.imageTintList = null - } icon.setImageIcon(it) + icon.imageTintList = it.tintList } ?: run { if (drawable is StateListDrawable) { // Only reset the drawable if it is a different resource, as it will interfere diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt new file mode 100644 index 0000000000000..47ab17dd7ed00 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2021 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.app.PendingIntent +import android.content.ComponentName +import android.content.res.ColorStateList +import android.graphics.drawable.GradientDrawable +import android.graphics.drawable.Icon +import android.service.controls.Control +import android.service.controls.DeviceTypes +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.test.filters.SmallTest +import com.android.systemui.R +import com.android.systemui.controls.controller.ControlsController +import com.android.systemui.util.time.FakeSystemClock +import org.junit.runner.RunWith +import com.android.systemui.SysuiTestCase +import com.android.systemui.controls.ControlsMetricsLogger +import com.android.systemui.controls.controller.ControlInfo +import com.android.systemui.util.concurrency.FakeExecutor +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.mockito.Mockito.mock + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +class ControlViewHolderTest : SysuiTestCase() { + + private val clock = FakeSystemClock() + + private lateinit var cvh: ControlViewHolder + + @Before + fun setUp() { + TestableLooper.get(this).runWithLooper { + val baseLayout = LayoutInflater.from(mContext).inflate( + R.layout.controls_base_item, null, false) as ViewGroup + + cvh = ControlViewHolder( + baseLayout, + mock(ControlsController::class.java), + FakeExecutor(clock), + FakeExecutor(clock), + mock(ControlActionCoordinator::class.java), + mock(ControlsMetricsLogger::class.java), + uid = 100 + ) + + val cws = ControlWithState( + ComponentName.createRelative("pkg", "cls"), + ControlInfo( + CONTROL_ID, CONTROL_TITLE, "subtitle", DeviceTypes.TYPE_AIR_FRESHENER + ), + Control.StatelessBuilder(CONTROL_ID, mock(PendingIntent::class.java)).build() + ) + + cvh.bindData(cws, isLocked = false) + } + } + + @Test + fun updateStatusRow_customIconWithTint_iconTintRemains() { + val control = Control.StatelessBuilder(DEFAULT_CONTROL) + .setCustomIcon( + Icon.createWithResource(mContext.resources, R.drawable.ic_emergency_star) + .setTint(TINT_COLOR) + ) + .build() + + cvh.updateStatusRow(enabled = true, CONTROL_TITLE, DRAWABLE, COLOR, control) + + assertThat(cvh.icon.imageTintList).isEqualTo(ColorStateList.valueOf(TINT_COLOR)) + } + + @Test + fun updateStatusRow_customIconWithTintList_iconTintListRemains() { + val customIconTintList = ColorStateList.valueOf(TINT_COLOR) + val control = Control.StatelessBuilder(CONTROL_ID, mock(PendingIntent::class.java)) + .setCustomIcon( + Icon.createWithResource(mContext.resources, R.drawable.ic_emergency_star) + .setTintList(customIconTintList) + ) + .build() + + cvh.updateStatusRow(enabled = true, CONTROL_TITLE, DRAWABLE, COLOR, control) + + assertThat(cvh.icon.imageTintList).isEqualTo(customIconTintList) + } +} + +private const val CONTROL_ID = "CONTROL_ID" +private const val CONTROL_TITLE = "CONTROL_TITLE" +private const val TINT_COLOR = 0x00ff00 // Should be different from [COLOR] + +private val DRAWABLE = GradientDrawable() +private val COLOR = ColorStateList.valueOf(0xffff00) +private val DEFAULT_CONTROL = Control.StatelessBuilder( + CONTROL_ID, mock(PendingIntent::class.java)).build() \ No newline at end of file