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 static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
20 import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
21 import static com.android.systemui.flags.Flags.LOCKSCREEN_ENABLE_LANDSCAPE;
22 import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
23 
24 import static org.mockito.Mockito.any;
25 import static org.mockito.Mockito.anyInt;
26 import static org.mockito.Mockito.reset;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.Context;
31 import android.content.res.Resources;
32 import android.graphics.Point;
33 import android.graphics.Rect;
34 import android.graphics.drawable.AnimatedStateListDrawable;
35 import android.util.Pair;
36 import android.view.View;
37 import android.view.WindowManager;
38 import android.view.accessibility.AccessibilityManager;
39 import android.widget.ImageView;
40 
41 import com.android.systemui.Flags;
42 import com.android.systemui.SysuiTestCase;
43 import com.android.systemui.biometrics.AuthController;
44 import com.android.systemui.biometrics.AuthRippleController;
45 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
46 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor;
47 import com.android.systemui.doze.util.BurnInHelperKt;
48 import com.android.systemui.dump.DumpManager;
49 import com.android.systemui.flags.FakeFeatureFlags;
50 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
51 import com.android.systemui.kosmos.KosmosJavaAdapter;
52 import com.android.systemui.plugins.FalsingManager;
53 import com.android.systemui.plugins.statusbar.StatusBarStateController;
54 import com.android.systemui.res.R;
55 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
56 import com.android.systemui.statusbar.StatusBarState;
57 import com.android.systemui.statusbar.VibratorHelper;
58 import com.android.systemui.statusbar.policy.ConfigurationController;
59 import com.android.systemui.statusbar.policy.KeyguardStateController;
60 import com.android.systemui.util.concurrency.FakeExecutor;
61 import com.android.systemui.util.time.FakeSystemClock;
62 
63 import org.junit.After;
64 import org.junit.Before;
65 import org.mockito.Answers;
66 import org.mockito.ArgumentCaptor;
67 import org.mockito.Captor;
68 import org.mockito.Mock;
69 import org.mockito.MockitoAnnotations;
70 import org.mockito.MockitoSession;
71 import org.mockito.quality.Strictness;
72 
73 public class LegacyLockIconViewControllerBaseTest extends SysuiTestCase {
74     protected static final String UNLOCKED_LABEL = "unlocked";
75     protected static final String LOCKED_LABEL = "locked";
76     protected static final int PADDING = 10;
77 
78     protected MockitoSession mStaticMockSession;
79 
80     protected final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
81     protected @Mock DeviceEntryInteractor mDeviceEntryInteractor;
82     protected @Mock LockIconView mLockIconView;
83     protected @Mock ImageView mLockIcon;
84     protected @Mock AnimatedStateListDrawable mIconDrawable;
85     protected @Mock Context mContext;
86     protected @Mock Resources mResources;
87     protected @Mock(answer = Answers.RETURNS_DEEP_STUBS) WindowManager mWindowManager;
88     protected @Mock StatusBarStateController mStatusBarStateController;
89     protected @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
90     protected @Mock KeyguardViewController mKeyguardViewController;
91     protected @Mock KeyguardStateController mKeyguardStateController;
92     protected @Mock FalsingManager mFalsingManager;
93     protected @Mock AuthController mAuthController;
94     protected @Mock DumpManager mDumpManager;
95     protected @Mock AccessibilityManager mAccessibilityManager;
96     protected @Mock ConfigurationController mConfigurationController;
97     protected @Mock VibratorHelper mVibrator;
98     protected @Mock AuthRippleController mAuthRippleController;
99     protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
100     protected FakeFeatureFlags mFeatureFlags;
101 
102     protected @Mock PrimaryBouncerInteractor mPrimaryBouncerInteractor;
103 
104     protected LegacyLockIconViewController mUnderTest;
105 
106     // Capture listeners so that they can be used to send events
107     @Captor protected ArgumentCaptor<View.OnAttachStateChangeListener> mAttachCaptor =
108             ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
109 
110     @Captor protected ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateCaptor =
111             ArgumentCaptor.forClass(KeyguardStateController.Callback.class);
112     protected KeyguardStateController.Callback mKeyguardStateCallback;
113 
114     @Captor protected ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateCaptor =
115             ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
116     protected StatusBarStateController.StateListener mStatusBarStateListener;
117 
118     @Captor protected ArgumentCaptor<AuthController.Callback> mAuthControllerCallbackCaptor;
119     protected AuthController.Callback mAuthControllerCallback;
120 
121     @Captor protected ArgumentCaptor<KeyguardUpdateMonitorCallback>
122             mKeyguardUpdateMonitorCallbackCaptor =
123             ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
124     protected KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
125 
126     @Captor protected ArgumentCaptor<Point> mPointCaptor;
127 
128     @Before
setUp()129     public void setUp() throws Exception {
130         mStaticMockSession = mockitoSession()
131                 .mockStatic(BurnInHelperKt.class)
132                 .strictness(Strictness.LENIENT)
133                 .startMocking();
134         MockitoAnnotations.initMocks(this);
135 
136         setupLockIconViewMocks();
137         when(mContext.getResources()).thenReturn(mResources);
138         when(mContext.getSystemService(WindowManager.class)).thenReturn(mWindowManager);
139         Rect windowBounds = new Rect(0, 0, 800, 1200);
140         when(mWindowManager.getCurrentWindowMetrics().getBounds()).thenReturn(windowBounds);
141         when(mResources.getString(R.string.accessibility_unlock_button)).thenReturn(UNLOCKED_LABEL);
142         when(mResources.getString(R.string.accessibility_lock_icon)).thenReturn(LOCKED_LABEL);
143         when(mResources.getDrawable(anyInt(), any())).thenReturn(mIconDrawable);
144         when(mResources.getDimensionPixelSize(R.dimen.lock_icon_padding)).thenReturn(PADDING);
145         when(mAuthController.getScaleFactor()).thenReturn(1f);
146 
147         when(mKeyguardStateController.isShowing()).thenReturn(true);
148         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
149         when(mStatusBarStateController.isDozing()).thenReturn(false);
150         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
151 
152         if (!SceneContainerFlag.isEnabled()) {
153             mSetFlagsRule.disableFlags(Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR);
154             mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT);
155         }
156 
157         mFeatureFlags = new FakeFeatureFlags();
158         mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
159         mFeatureFlags.set(LOCKSCREEN_ENABLE_LANDSCAPE, false);
160 
161         mUnderTest = new LegacyLockIconViewController(
162                 mStatusBarStateController,
163                 mKeyguardUpdateMonitor,
164                 mKeyguardViewController,
165                 mKeyguardStateController,
166                 mFalsingManager,
167                 mAuthController,
168                 mDumpManager,
169                 mAccessibilityManager,
170                 mConfigurationController,
171                 mDelayableExecutor,
172                 mVibrator,
173                 mAuthRippleController,
174                 mResources,
175                 mKosmos.getKeyguardTransitionInteractor(),
176                 KeyguardInteractorFactory.create(mFeatureFlags).getKeyguardInteractor(),
177                 mFeatureFlags,
178                 mPrimaryBouncerInteractor,
179                 mContext,
180                 () -> mDeviceEntryInteractor
181         );
182     }
183 
184     @After
tearDown()185     public void tearDown() {
186         mStaticMockSession.finishMocking();
187     }
188 
setupUdfps()189     protected Pair<Float, Point> setupUdfps() {
190         when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
191         final Point udfpsLocation = new Point(50, 75);
192         final float radius = 33f;
193         when(mAuthController.getUdfpsLocation()).thenReturn(udfpsLocation);
194         when(mAuthController.getUdfpsRadius()).thenReturn(radius);
195 
196         return new Pair(radius, udfpsLocation);
197     }
198 
setupShowLockIcon()199     protected void setupShowLockIcon() {
200         when(mKeyguardStateController.isShowing()).thenReturn(true);
201         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
202         when(mStatusBarStateController.isDozing()).thenReturn(false);
203         when(mStatusBarStateController.getDozeAmount()).thenReturn(0f);
204         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
205         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
206     }
207 
captureAuthControllerCallback()208     protected void captureAuthControllerCallback() {
209         verify(mAuthController).addCallback(mAuthControllerCallbackCaptor.capture());
210         mAuthControllerCallback = mAuthControllerCallbackCaptor.getValue();
211     }
212 
captureKeyguardStateCallback()213     protected void captureKeyguardStateCallback() {
214         verify(mKeyguardStateController).addCallback(mKeyguardStateCaptor.capture());
215         mKeyguardStateCallback = mKeyguardStateCaptor.getValue();
216     }
217 
captureStatusBarStateListener()218     protected void captureStatusBarStateListener() {
219         verify(mStatusBarStateController).addCallback(mStatusBarStateCaptor.capture());
220         mStatusBarStateListener = mStatusBarStateCaptor.getValue();
221     }
222 
captureKeyguardUpdateMonitorCallback()223     protected void captureKeyguardUpdateMonitorCallback() {
224         verify(mKeyguardUpdateMonitor).registerCallback(
225                 mKeyguardUpdateMonitorCallbackCaptor.capture());
226         mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue();
227     }
228 
setupLockIconViewMocks()229     protected void setupLockIconViewMocks() {
230         when(mLockIconView.getResources()).thenReturn(mResources);
231         when(mLockIconView.getContext()).thenReturn(mContext);
232         when(mLockIconView.getLockIcon()).thenReturn(mLockIcon);
233     }
234 
resetLockIconView()235     protected void resetLockIconView() {
236         reset(mLockIconView);
237         setupLockIconViewMocks();
238     }
239 
init(boolean useDozeMigrationFlag)240     protected void init(boolean useDozeMigrationFlag) {
241         mFeatureFlags.set(DOZING_MIGRATION_1, useDozeMigrationFlag);
242         mUnderTest.setLockIconView(mLockIconView);
243     }
244 }
245