1 /* <lambda>null2 * Copyright (C) 2022 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 18 package com.android.systemui.keyguard.data.quickaffordance 19 20 import androidx.test.filters.SmallTest 21 import com.android.systemui.R 22 import com.android.systemui.SysuiTestCase 23 import com.android.systemui.controls.ControlsServiceInfo 24 import com.android.systemui.controls.controller.ControlsController 25 import com.android.systemui.controls.dagger.ControlsComponent 26 import com.android.systemui.controls.management.ControlsListingController 27 import com.android.systemui.util.mockito.mock 28 import com.android.systemui.util.mockito.whenever 29 import com.google.common.truth.Truth.assertThat 30 import java.util.Optional 31 import kotlinx.coroutines.flow.MutableStateFlow 32 import kotlinx.coroutines.flow.launchIn 33 import kotlinx.coroutines.flow.onEach 34 import kotlinx.coroutines.test.runBlockingTest 35 import org.junit.Before 36 import org.junit.Test 37 import org.junit.runner.RunWith 38 import org.junit.runners.Parameterized 39 import org.junit.runners.Parameterized.Parameter 40 import org.junit.runners.Parameterized.Parameters 41 import org.mockito.ArgumentCaptor 42 import org.mockito.Captor 43 import org.mockito.Mock 44 import org.mockito.Mockito.verify 45 import org.mockito.MockitoAnnotations 46 47 @SmallTest 48 @RunWith(Parameterized::class) 49 class HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest : SysuiTestCase() { 50 51 companion object { 52 @Parameters( 53 name = 54 "feature enabled = {0}, has favorites = {1}, has panels = {2}, " + 55 "has service infos = {3}, can show while locked = {4}, " + 56 "visibility is AVAILABLE {5} - expected visible = {6}" 57 ) 58 @JvmStatic 59 fun data() = 60 (0 until 64) 61 .map { combination -> 62 arrayOf( 63 /* isFeatureEnabled= */ combination and 0b100000 != 0, 64 /* hasFavorites = */ combination and 0b010000 != 0, 65 /* hasPanels = */ combination and 0b001000 != 0, 66 /* hasServiceInfos= */ combination and 0b000100 != 0, 67 /* canShowWhileLocked= */ combination and 0b000010 != 0, 68 /* visibilityAvailable= */ combination and 0b000001 != 0, 69 /* isVisible= */ combination in setOf(0b111111, 0b110111, 0b101111), 70 ) 71 } 72 .toList() 73 } 74 75 @Mock private lateinit var component: ControlsComponent 76 @Mock private lateinit var controlsController: ControlsController 77 @Mock private lateinit var controlsListingController: ControlsListingController 78 @Mock private lateinit var controlsServiceInfo: ControlsServiceInfo 79 @Captor 80 private lateinit var callbackCaptor: 81 ArgumentCaptor<ControlsListingController.ControlsListingCallback> 82 83 private lateinit var underTest: HomeControlsKeyguardQuickAffordanceConfig 84 85 @JvmField @Parameter(0) var isFeatureEnabled: Boolean = false 86 @JvmField @Parameter(1) var hasFavorites: Boolean = false 87 @JvmField @Parameter(2) var hasPanels: Boolean = false 88 @JvmField @Parameter(3) var hasServiceInfos: Boolean = false 89 @JvmField @Parameter(4) var canShowWhileLocked: Boolean = false 90 @JvmField @Parameter(5) var isVisibilityAvailable: Boolean = false 91 @JvmField @Parameter(6) var isVisibleExpected: Boolean = false 92 93 @Before 94 fun setUp() { 95 MockitoAnnotations.initMocks(this) 96 whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon) 97 whenever(component.getTileTitleId()).thenReturn(R.string.quick_controls_title) 98 whenever(component.getControlsController()).thenReturn(Optional.of(controlsController)) 99 whenever(component.getControlsListingController()) 100 .thenReturn(Optional.of(controlsListingController)) 101 if (hasPanels) { 102 whenever(controlsServiceInfo.panelActivity).thenReturn(mock()) 103 } 104 whenever(controlsListingController.getCurrentServices()) 105 .thenReturn( 106 if (hasServiceInfos) { 107 listOf(controlsServiceInfo, mock()) 108 } else { 109 emptyList() 110 } 111 ) 112 whenever(component.canShowWhileLockedSetting) 113 .thenReturn(MutableStateFlow(canShowWhileLocked)) 114 whenever(component.getVisibility()) 115 .thenReturn( 116 if (isVisibilityAvailable) { 117 ControlsComponent.Visibility.AVAILABLE 118 } else { 119 ControlsComponent.Visibility.UNAVAILABLE 120 } 121 ) 122 123 underTest = 124 HomeControlsKeyguardQuickAffordanceConfig( 125 context = context, 126 component = component, 127 ) 128 } 129 130 @Test 131 fun state() = runBlockingTest { 132 whenever(component.isEnabled()).thenReturn(isFeatureEnabled) 133 whenever(controlsController.getFavorites()) 134 .thenReturn( 135 if (hasFavorites) { 136 listOf(mock()) 137 } else { 138 emptyList() 139 } 140 ) 141 val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() 142 val job = underTest.lockScreenState.onEach(values::add).launchIn(this) 143 144 if (canShowWhileLocked) { 145 val serviceInfoMock: ControlsServiceInfo = mock { 146 if (hasPanels) { 147 whenever(panelActivity).thenReturn(mock()) 148 } 149 } 150 verify(controlsListingController).addCallback(callbackCaptor.capture()) 151 callbackCaptor.value.onServicesUpdated( 152 if (hasServiceInfos) { 153 listOf(serviceInfoMock) 154 } else { 155 emptyList() 156 } 157 ) 158 } 159 160 assertThat(values.last()) 161 .isInstanceOf( 162 if (isVisibleExpected) { 163 KeyguardQuickAffordanceConfig.LockScreenState.Visible::class.java 164 } else { 165 KeyguardQuickAffordanceConfig.LockScreenState.Hidden::class.java 166 } 167 ) 168 assertThat(underTest.getPickerScreenState()) 169 .isInstanceOf( 170 when { 171 !isFeatureEnabled -> 172 KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice::class 173 .java 174 hasServiceInfos && hasFavorites -> 175 KeyguardQuickAffordanceConfig.PickerScreenState.Default::class.java 176 else -> KeyguardQuickAffordanceConfig.PickerScreenState.Disabled::class.java 177 } 178 ) 179 job.cancel() 180 } 181 } 182