1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.controls.ui 18 19 import android.app.PendingIntent 20 import android.content.ComponentName 21 import android.content.res.ColorStateList 22 import android.graphics.drawable.GradientDrawable 23 import android.graphics.drawable.Icon 24 import android.service.controls.Control 25 import android.service.controls.DeviceTypes 26 import android.service.controls.templates.ControlTemplate 27 import android.testing.TestableLooper 28 import android.view.LayoutInflater 29 import android.view.View 30 import android.view.ViewGroup 31 import androidx.test.ext.junit.runners.AndroidJUnit4 32 import androidx.test.filters.SmallTest 33 import com.android.systemui.res.R 34 import com.android.systemui.SysuiTestCase 35 import com.android.systemui.controls.ControlsMetricsLogger 36 import com.android.systemui.controls.controller.ControlInfo 37 import com.android.systemui.controls.controller.ControlsController 38 import com.android.systemui.util.concurrency.FakeExecutor 39 import com.android.systemui.util.time.FakeSystemClock 40 import com.google.common.truth.Truth.assertThat 41 import org.junit.Before 42 import org.junit.Test 43 import org.junit.runner.RunWith 44 import org.mockito.Mockito.mock 45 46 @SmallTest 47 @RunWith(AndroidJUnit4::class) 48 @TestableLooper.RunWithLooper 49 class ControlViewHolderTest : SysuiTestCase() { 50 51 private val clock = FakeSystemClock() 52 53 private lateinit var cvh: ControlViewHolder 54 private lateinit var baseLayout: ViewGroup 55 56 @Before setUpnull57 fun setUp() { 58 TestableLooper.get(this).runWithLooper { 59 baseLayout = LayoutInflater.from(mContext).inflate( 60 R.layout.controls_base_item, null, false) as ViewGroup 61 62 cvh = ControlViewHolder( 63 baseLayout, 64 mock(ControlsController::class.java), 65 FakeExecutor(clock), 66 FakeExecutor(clock), 67 mock(ControlActionCoordinator::class.java), 68 mock(ControlsMetricsLogger::class.java), 69 uid = 100, 70 0, 71 ) 72 73 val cws = ControlWithState( 74 ComponentName.createRelative("pkg", "cls"), 75 ControlInfo( 76 CONTROL_ID, CONTROL_TITLE, "subtitle", DeviceTypes.TYPE_AIR_FRESHENER 77 ), 78 Control.StatelessBuilder(CONTROL_ID, mock(PendingIntent::class.java)).build() 79 ) 80 81 cvh.bindData(cws, isLocked = false) 82 } 83 } 84 85 @Test updateStatusRow_customIconWithTint_iconTintRemainsnull86 fun updateStatusRow_customIconWithTint_iconTintRemains() { 87 val control = Control.StatelessBuilder(DEFAULT_CONTROL) 88 .setCustomIcon( 89 Icon.createWithResource(mContext.resources, R.drawable.ic_emergency_star) 90 .setTint(TINT_COLOR) 91 ) 92 .build() 93 94 cvh.updateStatusRow(enabled = true, CONTROL_TITLE, DRAWABLE, COLOR, control) 95 96 assertThat(cvh.icon.imageTintList).isEqualTo(ColorStateList.valueOf(TINT_COLOR)) 97 } 98 99 @Test updateStatusRow_customIconWithTintList_iconTintListRemainsnull100 fun updateStatusRow_customIconWithTintList_iconTintListRemains() { 101 val customIconTintList = ColorStateList.valueOf(TINT_COLOR) 102 val control = Control.StatelessBuilder(CONTROL_ID, mock(PendingIntent::class.java)) 103 .setCustomIcon( 104 Icon.createWithResource(mContext.resources, R.drawable.ic_emergency_star) 105 .setTintList(customIconTintList) 106 ) 107 .build() 108 109 cvh.updateStatusRow(enabled = true, CONTROL_TITLE, DRAWABLE, COLOR, control) 110 111 assertThat(cvh.icon.imageTintList).isEqualTo(customIconTintList) 112 } 113 114 @Test chevronIconnull115 fun chevronIcon() { 116 val control = Control.StatefulBuilder(CONTROL_ID, mock(PendingIntent::class.java)) 117 .setStatus(Control.STATUS_OK) 118 .setControlTemplate(ControlTemplate.NO_TEMPLATE) 119 .build() 120 val cws = ControlWithState( 121 ComponentName.createRelative("pkg", "cls"), 122 ControlInfo( 123 CONTROL_ID, CONTROL_TITLE, "subtitle", DeviceTypes.TYPE_AIR_FRESHENER 124 ), 125 control 126 ) 127 cvh.bindData(cws, false) 128 val chevronIcon = baseLayout.requireViewById<View>(R.id.chevron_icon) 129 130 assertThat(chevronIcon.visibility).isEqualTo(View.VISIBLE) 131 } 132 } 133 134 private const val CONTROL_ID = "CONTROL_ID" 135 private const val CONTROL_TITLE = "CONTROL_TITLE" 136 private const val TINT_COLOR = 0x00ff00 // Should be different from [COLOR] 137 138 private val DRAWABLE = GradientDrawable() 139 private val COLOR = ColorStateList.valueOf(0xffff00) 140 private val DEFAULT_CONTROL = Control.StatelessBuilder( 141 CONTROL_ID, mock(PendingIntent::class.java)).build() 142