• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.ArgumentMatchers.anyBoolean;
21 import static org.mockito.ArgumentMatchers.anyInt;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.never;
25 import static org.mockito.Mockito.reset;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.testing.TestableLooper;
30 import android.view.LayoutInflater;
31 import android.view.ViewGroup;
32 import android.view.WindowInsetsController;
33 
34 import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
35 import androidx.test.ext.junit.runners.AndroidJUnit4;
36 import androidx.test.filters.SmallTest;
37 
38 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
39 import com.android.systemui.SysuiTestCase;
40 import com.android.systemui.flags.FeatureFlags;
41 import com.android.systemui.res.R;
42 
43 import org.junit.Before;
44 import org.junit.Rule;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.mockito.ArgumentCaptor;
48 import org.mockito.Mock;
49 import org.mockito.junit.MockitoJUnit;
50 import org.mockito.junit.MockitoRule;
51 
52 @SmallTest
53 @RunWith(AndroidJUnit4.class)
54 @TestableLooper.RunWithLooper()
55 public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase {
56 
57     @Rule
58     public MockitoRule mRule = MockitoJUnit.rule();
59 
60     @Mock
61     private KeyguardSecurityViewFlipper mView;
62     @Mock
63     private LayoutInflater mLayoutInflater;
64     @Mock
65     private AsyncLayoutInflater mAsyncLayoutInflater;
66     @Mock
67     private KeyguardInputViewController.Factory mKeyguardSecurityViewControllerFactory;
68     @Mock
69     private EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
70     @Mock
71     private EmergencyButtonController mEmergencyButtonController;
72     @Mock
73     private KeyguardInputViewController mKeyguardInputViewController;
74     @Mock
75     private KeyguardInputView mInputView;
76     @Mock
77     private WindowInsetsController mWindowInsetsController;
78     @Mock
79     private KeyguardSecurityCallback mKeyguardSecurityCallback;
80     @Mock
81     private FeatureFlags mFeatureFlags;
82 
83     private KeyguardSecurityViewFlipperController mKeyguardSecurityViewFlipperController;
84 
85     @Before
setup()86     public void setup() {
87         when(mKeyguardSecurityViewControllerFactory.create(
88                 any(KeyguardInputView.class), any(SecurityMode.class),
89                 any(KeyguardSecurityCallback.class)))
90                 .thenReturn(mKeyguardInputViewController);
91         when(mView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
92         when(mEmergencyButtonControllerFactory.create(any(EmergencyButton.class)))
93                 .thenReturn(mEmergencyButtonController);
94         when(mView.getContext()).thenReturn(getContext());
95 
96         mKeyguardSecurityViewFlipperController = new KeyguardSecurityViewFlipperController(mView,
97                 mLayoutInflater, mAsyncLayoutInflater, mKeyguardSecurityViewControllerFactory,
98                 mEmergencyButtonControllerFactory, mFeatureFlags);
99     }
100 
101     @Test
showSecurityScreen_canInflateAllModes()102     public void showSecurityScreen_canInflateAllModes() {
103         SecurityMode[] modes = SecurityMode.values();
104         // Always return an invalid controller so that we're always making a new one.
105         when(mKeyguardInputViewController.getSecurityMode()).thenReturn(SecurityMode.Invalid);
106         for (SecurityMode mode : modes) {
107             reset(mLayoutInflater);
108             when(mLayoutInflater.inflate(anyInt(), eq(mView), eq(false)))
109                     .thenReturn(mInputView);
110             mKeyguardSecurityViewFlipperController.getSecurityView(mode, mKeyguardSecurityCallback,
111                     controller -> {
112                         if (mode == SecurityMode.Invalid || mode == SecurityMode.None) {
113                             verify(mLayoutInflater, never()).inflate(
114                                     anyInt(), any(ViewGroup.class), anyBoolean());
115                         } else {
116                             verify(mLayoutInflater).inflate(anyInt(), eq(mView), eq(false));
117                         }
118                     });
119         }
120     }
121 
122     @Test
getSecurityView_NotInflated()123     public void getSecurityView_NotInflated() {
124         mKeyguardSecurityViewFlipperController.clearViews();
125         mKeyguardSecurityViewFlipperController.getSecurityView(SecurityMode.PIN,
126                 mKeyguardSecurityCallback,
127                 controller -> {});
128         verify(mAsyncLayoutInflater).inflate(anyInt(), eq(mView), any(
129                 AsyncLayoutInflater.OnInflateFinishedListener.class));
130     }
131 
132     @Test
asynchronouslyInflateView_setNeedsInput()133     public void asynchronouslyInflateView_setNeedsInput() {
134         mKeyguardSecurityViewFlipperController.clearViews();
135         ArgumentCaptor<AsyncLayoutInflater.OnInflateFinishedListener> argumentCaptor =
136                 ArgumentCaptor.forClass(AsyncLayoutInflater.OnInflateFinishedListener.class);
137         mKeyguardSecurityViewFlipperController.getSecurityView(SecurityMode.PIN,
138                 mKeyguardSecurityCallback, controller -> {});
139         verify(mAsyncLayoutInflater).inflate(anyInt(), eq(mView), argumentCaptor.capture());
140         argumentCaptor.getValue().onInflateFinished(
141                 LayoutInflater.from(getContext()).inflate(R.layout.keyguard_pin_view, null),
142                 R.layout.keyguard_pin_view, mView);
143     }
144 
145     @Test
getSecurityView_multipleInvocations_callsAsyncInflateOnce()146     public void getSecurityView_multipleInvocations_callsAsyncInflateOnce() {
147         mKeyguardSecurityViewFlipperController.clearViews();
148         // Make 2 calls to get security view
149         var callback1 = mock(KeyguardSecurityViewFlipperController.OnViewInflatedCallback.class);
150         var callback2 = mock(KeyguardSecurityViewFlipperController.OnViewInflatedCallback.class);
151         mKeyguardSecurityViewFlipperController.getSecurityView(SecurityMode.PIN,
152                 mKeyguardSecurityCallback, callback1);
153         mKeyguardSecurityViewFlipperController.getSecurityView(SecurityMode.PIN,
154                 mKeyguardSecurityCallback, callback2);
155 
156         // Verify inflation is called once...
157         ArgumentCaptor<AsyncLayoutInflater.OnInflateFinishedListener> argumentCaptor =
158                 ArgumentCaptor.forClass(AsyncLayoutInflater.OnInflateFinishedListener.class);
159         verify(mAsyncLayoutInflater).inflate(anyInt(), eq(mView), argumentCaptor.capture());
160         argumentCaptor.getValue().onInflateFinished(
161                 LayoutInflater.from(getContext()).inflate(R.layout.keyguard_pin_view, null),
162                 R.layout.keyguard_pin_view, mView);
163 
164         // ... and both callbacks get invoked
165         verify(callback1).onViewInflated(mKeyguardInputViewController);
166         verify(callback2).onViewInflated(mKeyguardInputViewController);
167     }
168 
169     @Test
onDensityOrFontScaleChanged()170     public void onDensityOrFontScaleChanged() {
171         mKeyguardSecurityViewFlipperController.clearViews();
172         verify(mView).removeAllViews();
173     }
174 }
175