1 /* 2 * 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 package com.android.systemui.bouncer.ui.viewmodel 18 19 import android.os.Looper 20 import androidx.test.ext.junit.runners.AndroidJUnit4 21 import androidx.test.filters.SmallTest 22 import com.android.keyguard.KeyguardSecurityModel 23 import com.android.keyguard.KeyguardUpdateMonitor 24 import com.android.systemui.RoboPilotTest 25 import com.android.systemui.SysuiTestCase 26 import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository 27 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor 28 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor 29 import com.android.systemui.bouncer.shared.model.BouncerShowMessageModel 30 import com.android.systemui.bouncer.ui.BouncerView 31 import com.android.systemui.classifier.FalsingCollector 32 import com.android.systemui.coroutines.collectLastValue 33 import com.android.systemui.coroutines.collectValues 34 import com.android.systemui.flags.FakeFeatureFlags 35 import com.android.systemui.flags.Flags 36 import com.android.systemui.keyguard.DismissCallbackRegistry 37 import com.android.systemui.keyguard.data.repository.TrustRepository 38 import com.android.systemui.statusbar.phone.KeyguardBypassController 39 import com.android.systemui.statusbar.policy.KeyguardStateController 40 import com.android.systemui.utils.os.FakeHandler 41 import com.google.common.truth.Truth.assertThat 42 import kotlinx.coroutines.flow.launchIn 43 import kotlinx.coroutines.flow.onEach 44 import kotlinx.coroutines.test.TestScope 45 import kotlinx.coroutines.test.runCurrent 46 import kotlinx.coroutines.test.runTest 47 import org.junit.Before 48 import org.junit.Test 49 import org.junit.runner.RunWith 50 import org.mockito.Mock 51 import org.mockito.Mockito 52 import org.mockito.MockitoAnnotations 53 54 @SmallTest 55 @RoboPilotTest 56 @RunWith(AndroidJUnit4::class) 57 @kotlinx.coroutines.ExperimentalCoroutinesApi 58 class KeyguardBouncerViewModelTest : SysuiTestCase() { 59 lateinit var underTest: KeyguardBouncerViewModel 60 lateinit var bouncerInteractor: PrimaryBouncerInteractor 61 @Mock lateinit var bouncerView: BouncerView 62 @Mock private lateinit var keyguardStateController: KeyguardStateController 63 @Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel 64 @Mock private lateinit var primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor 65 @Mock private lateinit var falsingCollector: FalsingCollector 66 @Mock private lateinit var dismissCallbackRegistry: DismissCallbackRegistry 67 @Mock private lateinit var keyguardBypassController: KeyguardBypassController 68 @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor 69 private val mainHandler = FakeHandler(Looper.getMainLooper()) 70 val repository = FakeKeyguardBouncerRepository() 71 72 @Before 73 fun setup() { 74 MockitoAnnotations.initMocks(this) 75 bouncerInteractor = 76 PrimaryBouncerInteractor( 77 repository, 78 bouncerView, 79 mainHandler, 80 keyguardStateController, 81 keyguardSecurityModel, 82 primaryBouncerCallbackInteractor, 83 falsingCollector, 84 dismissCallbackRegistry, 85 context, 86 keyguardUpdateMonitor, 87 Mockito.mock(TrustRepository::class.java), 88 FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) }, 89 TestScope().backgroundScope, 90 ) 91 underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor) 92 } 93 94 @Test 95 fun setMessage() = runTest { 96 var message: BouncerShowMessageModel? = null 97 val job = underTest.bouncerShowMessage.onEach { message = it }.launchIn(this) 98 99 repository.setShowMessage(BouncerShowMessageModel("abc", null)) 100 // Run the tasks that are pending at this point of virtual time. 101 runCurrent() 102 assertThat(message?.message).isEqualTo("abc") 103 job.cancel() 104 } 105 106 @Test 107 fun shouldUpdateSideFps_show() = runTest { 108 var count = 0 109 val job = underTest.shouldUpdateSideFps.onEach { count++ }.launchIn(this) 110 repository.setPrimaryShow(true) 111 // Run the tasks that are pending at this point of virtual time. 112 runCurrent() 113 assertThat(count).isEqualTo(1) 114 job.cancel() 115 } 116 117 @Test 118 fun shouldUpdateSideFps_hide() = runTest { 119 repository.setPrimaryShow(true) 120 var count = 0 121 val job = underTest.shouldUpdateSideFps.onEach { count++ }.launchIn(this) 122 repository.setPrimaryShow(false) 123 // Run the tasks that are pending at this point of virtual time. 124 runCurrent() 125 assertThat(count).isEqualTo(1) 126 job.cancel() 127 } 128 129 @Test 130 fun sideFpsShowing() = runTest { 131 var sideFpsIsShowing = false 132 val job = underTest.sideFpsShowing.onEach { sideFpsIsShowing = it }.launchIn(this) 133 repository.setSideFpsShowing(true) 134 // Run the tasks that are pending at this point of virtual time. 135 runCurrent() 136 assertThat(sideFpsIsShowing).isEqualTo(true) 137 job.cancel() 138 } 139 140 @Test 141 fun isShowing() = runTest { 142 var isShowing: Boolean? = null 143 val job = underTest.isShowing.onEach { isShowing = it }.launchIn(this) 144 repository.setPrimaryShow(true) 145 // Run the tasks that are pending at this point of virtual time. 146 runCurrent() 147 assertThat(isShowing).isEqualTo(true) 148 job.cancel() 149 } 150 151 @Test 152 fun isNotShowing() = runTest { 153 var isShowing: Boolean? = null 154 val job = underTest.isShowing.onEach { isShowing = it }.launchIn(this) 155 repository.setPrimaryShow(false) 156 // Run the tasks that are pending at this point of virtual time. 157 runCurrent() 158 assertThat(isShowing).isEqualTo(false) 159 job.cancel() 160 } 161 162 @Test 163 fun keyguardPosition_noValueSet_emptyByDefault() = runTest { 164 val positionValues by collectValues(underTest.keyguardPosition) 165 166 runCurrent() 167 168 assertThat(positionValues).isEmpty() 169 } 170 171 @Test 172 fun keyguardPosition_valueSet_returnsValue() = runTest { 173 val position by collectLastValue(underTest.keyguardPosition) 174 runCurrent() 175 176 repository.setKeyguardPosition(123f) 177 runCurrent() 178 179 assertThat(position).isEqualTo(123f) 180 } 181 } 182