1 /* 2 * Copyright (C) 2023 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.keyguard 18 19 import android.hardware.input.InputManager 20 import android.telephony.TelephonyManager 21 import android.testing.TestableLooper 22 import android.view.LayoutInflater 23 import androidx.test.ext.junit.runners.AndroidJUnit4 24 import androidx.test.filters.SmallTest 25 import com.android.internal.util.LatencyTracker 26 import com.android.internal.widget.LockPatternUtils 27 import com.android.keyguard.domain.interactor.KeyguardKeyboardInteractor 28 import com.android.systemui.Flags 29 import com.android.systemui.SysuiTestCase 30 import com.android.systemui.classifier.FalsingCollector 31 import com.android.systemui.flags.FakeFeatureFlags 32 import com.android.systemui.haptics.msdl.bouncerHapticPlayer 33 import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository 34 import com.android.systemui.res.R 35 import com.android.systemui.testKosmos 36 import com.android.systemui.user.domain.interactor.SelectedUserInteractor 37 import com.android.systemui.util.mockito.any 38 import com.android.systemui.util.mockito.mock 39 import org.junit.Before 40 import org.junit.Test 41 import org.junit.runner.RunWith 42 import org.mockito.ArgumentCaptor 43 import org.mockito.ArgumentMatchers.anyString 44 import org.mockito.Mock 45 import org.mockito.Mockito 46 import org.mockito.Mockito.anyInt 47 import org.mockito.Mockito.never 48 import org.mockito.Mockito.reset 49 import org.mockito.Mockito.verify 50 import org.mockito.Mockito.`when` 51 import org.mockito.MockitoAnnotations 52 53 @SmallTest 54 @RunWith(AndroidJUnit4::class) 55 // collectFlow in KeyguardPinBasedInputViewController.onViewAttached calls JavaAdapter.CollectFlow, 56 // which calls View.onRepeatWhenAttached, which requires being run on main thread. 57 @TestableLooper.RunWithLooper(setAsMainLooper = true) 58 class KeyguardSimPinViewControllerTest : SysuiTestCase() { 59 private lateinit var simPinView: KeyguardSimPinView 60 private lateinit var underTest: KeyguardSimPinViewController 61 @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor 62 @Mock private lateinit var securityMode: KeyguardSecurityModel.SecurityMode 63 @Mock private lateinit var lockPatternUtils: LockPatternUtils 64 @Mock private lateinit var keyguardSecurityCallback: KeyguardSecurityCallback 65 @Mock private lateinit var messageAreaControllerFactory: KeyguardMessageAreaController.Factory 66 @Mock private lateinit var latencyTracker: LatencyTracker 67 @Mock private lateinit var telephonyManager: TelephonyManager 68 @Mock private lateinit var falsingCollector: FalsingCollector 69 @Mock private lateinit var emergencyButtonController: EmergencyButtonController 70 @Mock private lateinit var mSelectedUserInteractor: SelectedUserInteractor 71 @Mock 72 private lateinit var keyguardMessageAreaController: 73 KeyguardMessageAreaController<BouncerKeyguardMessageArea> 74 @Mock private lateinit var mUserActivityNotifier: UserActivityNotifier 75 private val updateMonitorCallbackArgumentCaptor = 76 ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java) 77 @Mock private lateinit var inputManager: InputManager 78 79 private val kosmos = testKosmos() 80 81 @Before setupnull82 fun setup() { 83 MockitoAnnotations.initMocks(this) 84 `when`(messageAreaControllerFactory.create(Mockito.any(KeyguardMessageArea::class.java))) 85 .thenReturn(keyguardMessageAreaController) 86 `when`(telephonyManager.createForSubscriptionId(anyInt())).thenReturn(telephonyManager) 87 `when`(telephonyManager.supplyIccLockPin(anyString())).thenReturn(mock()) 88 simPinView = 89 LayoutInflater.from(context).inflate(R.layout.keyguard_sim_pin_view, null) 90 as KeyguardSimPinView 91 val fakeFeatureFlags = FakeFeatureFlags() 92 val keyguardKeyboardInteractor = KeyguardKeyboardInteractor(FakeKeyboardRepository()) 93 94 mSetFlagsRule.enableFlags(Flags.FLAG_REVAMPED_BOUNCER_MESSAGES) 95 underTest = 96 KeyguardSimPinViewController( 97 simPinView, 98 keyguardUpdateMonitor, 99 securityMode, 100 lockPatternUtils, 101 keyguardSecurityCallback, 102 messageAreaControllerFactory, 103 latencyTracker, 104 telephonyManager, 105 falsingCollector, 106 emergencyButtonController, 107 fakeFeatureFlags, 108 mSelectedUserInteractor, 109 keyguardKeyboardInteractor, 110 kosmos.bouncerHapticPlayer, 111 mUserActivityNotifier, 112 inputManager, 113 ) 114 underTest.init() 115 underTest.onViewAttached() 116 underTest.onResume(0) 117 verify(keyguardUpdateMonitor) 118 .registerCallback(updateMonitorCallbackArgumentCaptor.capture()) 119 reset(keyguardMessageAreaController) 120 reset(keyguardUpdateMonitor) 121 } 122 123 @Test onViewAttachednull124 fun onViewAttached() { 125 underTest.onViewAttached() 126 verify(keyguardMessageAreaController).setIsVisible(true) 127 verify(keyguardMessageAreaController) 128 .setMessage(context.resources.getString(R.string.keyguard_enter_your_pin), false) 129 verify(keyguardUpdateMonitor) 130 .registerCallback(any(KeyguardUpdateMonitorCallback::class.java)) 131 } 132 133 @Test onViewDetachednull134 fun onViewDetached() { 135 underTest.onViewDetached() 136 verify(keyguardUpdateMonitor).removeCallback(any(KeyguardUpdateMonitorCallback::class.java)) 137 } 138 139 @Test onResumenull140 fun onResume() { 141 underTest.onResume(KeyguardSecurityView.VIEW_REVEALED) 142 } 143 144 @Test onPausenull145 fun onPause() { 146 underTest.onPause() 147 } 148 149 @Test startAppearAnimationnull150 fun startAppearAnimation() { 151 underTest.startAppearAnimation() 152 } 153 154 @Test startDisappearAnimationnull155 fun startDisappearAnimation() { 156 underTest.startDisappearAnimation {} 157 } 158 159 @Test resetStatenull160 fun resetState() { 161 underTest.resetState() 162 verify(keyguardMessageAreaController).setMessage("") 163 } 164 165 @Test onSimStateChangedFromPinToPuk_showsCurrentSecurityScreennull166 fun onSimStateChangedFromPinToPuk_showsCurrentSecurityScreen() { 167 updateMonitorCallbackArgumentCaptor.value.onSimStateChanged( 168 /* subId= */ 0, 169 /* slotId= */ 0, 170 TelephonyManager.SIM_STATE_PIN_REQUIRED, 171 ) 172 verify(keyguardSecurityCallback, never()).showCurrentSecurityScreen() 173 174 updateMonitorCallbackArgumentCaptor.value.onSimStateChanged( 175 /* subId= */ 0, 176 /* slotId= */ 0, 177 TelephonyManager.SIM_STATE_PUK_REQUIRED, 178 ) 179 180 verify(keyguardSecurityCallback).showCurrentSecurityScreen() 181 } 182 } 183