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.keyguard
18 
19 import android.testing.AndroidTestingRunner
20 import android.testing.TestableLooper
21 import android.view.inputmethod.InputMethodManager
22 import android.widget.EditText
23 import android.widget.ImageView
24 import androidx.test.filters.SmallTest
25 import com.android.internal.util.LatencyTracker
26 import com.android.internal.widget.LockPatternUtils
27 import com.android.systemui.R
28 import com.android.systemui.SysuiTestCase
29 import com.android.systemui.classifier.FalsingCollector
30 import com.android.systemui.flags.FakeFeatureFlags
31 import com.android.systemui.flags.Flags
32 import com.android.systemui.util.concurrency.DelayableExecutor
33 import com.android.systemui.util.mockito.whenever
34 import org.junit.Before
35 import org.junit.Test
36 import org.junit.runner.RunWith
37 import org.mockito.ArgumentMatchers.anyBoolean
38 import org.mockito.ArgumentMatchers.anyString
39 import org.mockito.Mock
40 import org.mockito.Mockito
41 import org.mockito.Mockito.mock
42 import org.mockito.Mockito.never
43 import org.mockito.Mockito.verify
44 import org.mockito.Mockito.`when`
45 import org.mockito.MockitoAnnotations
46 
47 @SmallTest
48 @RunWith(AndroidTestingRunner::class)
49 @TestableLooper.RunWithLooper
50 class KeyguardPasswordViewControllerTest : SysuiTestCase() {
51     @Mock private lateinit var keyguardPasswordView: KeyguardPasswordView
52     @Mock private lateinit var passwordEntry: EditText
53     @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
54     @Mock lateinit var securityMode: KeyguardSecurityModel.SecurityMode
55     @Mock lateinit var lockPatternUtils: LockPatternUtils
56     @Mock lateinit var keyguardSecurityCallback: KeyguardSecurityCallback
57     @Mock lateinit var messageAreaControllerFactory: KeyguardMessageAreaController.Factory
58     @Mock lateinit var latencyTracker: LatencyTracker
59     @Mock lateinit var inputMethodManager: InputMethodManager
60     @Mock lateinit var emergencyButtonController: EmergencyButtonController
61     @Mock lateinit var mainExecutor: DelayableExecutor
62     @Mock lateinit var falsingCollector: FalsingCollector
63     @Mock lateinit var keyguardViewController: KeyguardViewController
64     @Mock private lateinit var mKeyguardMessageArea: BouncerKeyguardMessageArea
65     @Mock
66     private lateinit var mKeyguardMessageAreaController:
67         KeyguardMessageAreaController<BouncerKeyguardMessageArea>
68 
69     private lateinit var keyguardPasswordViewController: KeyguardPasswordViewController
70 
71     @Before
72     fun setup() {
73         MockitoAnnotations.initMocks(this)
74         Mockito.`when`(
75                 keyguardPasswordView.requireViewById<BouncerKeyguardMessageArea>(
76                     R.id.bouncer_message_area
77                 )
78             )
79             .thenReturn(mKeyguardMessageArea)
80         Mockito.`when`(messageAreaControllerFactory.create(mKeyguardMessageArea))
81             .thenReturn(mKeyguardMessageAreaController)
82         Mockito.`when`(keyguardPasswordView.passwordTextViewId).thenReturn(R.id.passwordEntry)
83         Mockito.`when`(keyguardPasswordView.findViewById<EditText>(R.id.passwordEntry))
84             .thenReturn(passwordEntry)
85         whenever(keyguardPasswordView.findViewById<ImageView>(R.id.switch_ime_button))
86             .thenReturn(mock(ImageView::class.java))
87         `when`(keyguardPasswordView.resources).thenReturn(context.resources)
88         val fakeFeatureFlags = FakeFeatureFlags()
89         fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
90         keyguardPasswordViewController =
91             KeyguardPasswordViewController(
92                 keyguardPasswordView,
93                 keyguardUpdateMonitor,
94                 securityMode,
95                 lockPatternUtils,
96                 keyguardSecurityCallback,
97                 messageAreaControllerFactory,
98                 latencyTracker,
99                 inputMethodManager,
100                 emergencyButtonController,
101                 mainExecutor,
102                 mContext.resources,
103                 falsingCollector,
104                 keyguardViewController,
105                 fakeFeatureFlags
106             )
107     }
108 
109     @Test
110     fun testFocusWhenBouncerIsShown() {
111         Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(true)
112         Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
113         keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
114         keyguardPasswordView.post {
115             verify(keyguardPasswordView).requestFocus()
116             verify(keyguardPasswordView).showKeyboard()
117         }
118     }
119 
120     @Test
121     fun testDoNotFocusWhenBouncerIsHidden() {
122         Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(false)
123         Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
124         keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
125         verify(keyguardPasswordView, never()).requestFocus()
126     }
127 
128     @Test
129     fun testHideKeyboardWhenOnPause() {
130         keyguardPasswordViewController.onPause()
131         keyguardPasswordView.post {
132             verify(keyguardPasswordView).clearFocus()
133             verify(keyguardPasswordView).hideKeyboard()
134         }
135     }
136 
137     @Test
138     fun testOnViewAttached() {
139         keyguardPasswordViewController.onViewAttached()
140         verify(mKeyguardMessageAreaController)
141             .setMessage(context.resources.getString(R.string.keyguard_enter_your_password), false)
142     }
143 
144     @Test
145     fun testOnViewAttached_withExistingMessage() {
146         `when`(mKeyguardMessageAreaController.message).thenReturn("Unlock to continue.")
147         keyguardPasswordViewController.onViewAttached()
148         verify(mKeyguardMessageAreaController, never()).setMessage(anyString(), anyBoolean())
149     }
150 
151     @Test
152     fun testMessageIsSetWhenReset() {
153         keyguardPasswordViewController.resetState()
154         verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_password)
155     }
156 }
157