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