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.systemui.statusbar;
18 
19 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
20 
21 import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
22 import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX;
23 import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
24 import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
25 
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.anyBoolean;
28 import static org.mockito.ArgumentMatchers.anyInt;
29 import static org.mockito.ArgumentMatchers.anyString;
30 import static org.mockito.Mockito.clearInvocations;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.reset;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 
36 import android.app.AlarmManager;
37 import android.app.Instrumentation;
38 import android.app.admin.DevicePolicyManager;
39 import android.app.admin.DevicePolicyResourcesManager;
40 import android.app.trust.TrustManager;
41 import android.content.BroadcastReceiver;
42 import android.content.ComponentName;
43 import android.content.Context;
44 import android.hardware.fingerprint.FingerprintManager;
45 import android.os.Looper;
46 import android.os.UserManager;
47 import android.provider.DeviceConfig;
48 import android.testing.TestableLooper;
49 import android.view.ViewGroup;
50 import android.view.accessibility.AccessibilityManager;
51 
52 import androidx.test.InstrumentationRegistry;
53 
54 import com.android.internal.app.IBatteryStats;
55 import com.android.internal.widget.LockPatternUtils;
56 import com.android.keyguard.KeyguardUpdateMonitor;
57 import com.android.keyguard.KeyguardUpdateMonitorCallback;
58 import com.android.keyguard.logging.KeyguardLogger;
59 import com.android.systemui.R;
60 import com.android.systemui.SysuiTestCase;
61 import com.android.systemui.biometrics.AuthController;
62 import com.android.systemui.biometrics.FaceHelpMessageDeferral;
63 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
64 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
65 import com.android.systemui.broadcast.BroadcastDispatcher;
66 import com.android.systemui.dock.DockManager;
67 import com.android.systemui.flags.FakeFeatureFlags;
68 import com.android.systemui.keyguard.KeyguardIndication;
69 import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
70 import com.android.systemui.keyguard.ScreenLifecycle;
71 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
72 import com.android.systemui.keyguard.util.IndicationHelper;
73 import com.android.systemui.plugins.FalsingManager;
74 import com.android.systemui.plugins.statusbar.StatusBarStateController;
75 import com.android.systemui.settings.UserTracker;
76 import com.android.systemui.statusbar.phone.KeyguardBypassController;
77 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
78 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
79 import com.android.systemui.statusbar.policy.KeyguardStateController;
80 import com.android.systemui.util.concurrency.FakeExecutor;
81 import com.android.systemui.util.time.FakeSystemClock;
82 import com.android.systemui.util.wakelock.WakeLockFake;
83 
84 import org.junit.After;
85 import org.junit.Before;
86 import org.mockito.ArgumentCaptor;
87 import org.mockito.Captor;
88 import org.mockito.Mock;
89 import org.mockito.MockitoAnnotations;
90 
91 public class KeyguardIndicationControllerBaseTest extends SysuiTestCase {
92 
93     protected static final String ORGANIZATION_NAME = "organization";
94 
95     protected static final ComponentName DEVICE_OWNER_COMPONENT = new ComponentName(
96             "com.android.foo",
97             "bar");
98 
99     protected static final int TEST_STRING_RES = R.string.keyguard_indication_trust_unlocked;
100 
101     protected String mDisclosureWithOrganization;
102     protected String mDisclosureGeneric;
103     protected String mFinancedDisclosureWithOrganization;
104 
105     @Mock
106     protected DevicePolicyManager mDevicePolicyManager;
107     @Mock
108     protected DevicePolicyResourcesManager mDevicePolicyResourcesManager;
109     @Mock
110     protected ViewGroup mIndicationArea;
111     @Mock
112     protected KeyguardStateController mKeyguardStateController;
113     @Mock
114     protected KeyguardIndicationTextView mIndicationAreaBottom;
115     @Mock
116     protected BroadcastDispatcher mBroadcastDispatcher;
117     @Mock
118     protected StatusBarStateController mStatusBarStateController;
119     @Mock
120     protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
121     @Mock
122     protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
123     @Mock
124     protected UserManager mUserManager;
125     @Mock
126     protected IBatteryStats mIBatteryStats;
127     @Mock
128     protected DockManager mDockManager;
129     @Mock
130     protected KeyguardIndicationRotateTextViewController mRotateTextViewController;
131     @Mock
132     protected FalsingManager mFalsingManager;
133     @Mock
134     protected LockPatternUtils mLockPatternUtils;
135     @Mock
136     protected KeyguardBypassController mKeyguardBypassController;
137     @Mock
138     protected AccessibilityManager mAccessibilityManager;
139     @Mock
140     protected FaceHelpMessageDeferral mFaceHelpMessageDeferral;
141     @Mock
142     protected AlternateBouncerInteractor mAlternateBouncerInteractor;
143     @Mock
144     protected ScreenLifecycle mScreenLifecycle;
145     @Mock
146     protected AuthController mAuthController;
147     @Mock
148     protected AlarmManager mAlarmManager;
149     @Mock
150     protected UserTracker mUserTracker;
151     @Captor
152     protected ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
153     @Captor
154     protected ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
155     @Captor
156     protected ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
157     @Captor
158     protected ArgumentCaptor<KeyguardIndication> mKeyguardIndicationCaptor;
159     @Captor
160     protected ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
161     @Captor
162     protected ArgumentCaptor<KeyguardStateController.Callback>
163             mKeyguardStateControllerCallbackCaptor;
164     @Captor
165     protected ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
166     protected KeyguardStateController.Callback mKeyguardStateControllerCallback;
167     protected KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
168     protected StatusBarStateController.StateListener mStatusBarStateListener;
169     protected ScreenLifecycle.Observer mScreenObserver;
170     protected BroadcastReceiver mBroadcastReceiver;
171     protected IndicationHelper mIndicationHelper;
172     protected FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
173     protected TestableLooper mTestableLooper;
174     protected final int mCurrentUserId = 1;
175 
176     protected KeyguardIndicationTextView mTextView; // AOD text
177 
178     protected KeyguardIndicationController mController;
179     protected WakeLockFake.Builder mWakeLockBuilder;
180     protected WakeLockFake mWakeLock;
181     protected Instrumentation mInstrumentation;
182     protected FakeFeatureFlags mFlags;
183 
184     @Before
setUp()185     public void setUp() throws Exception {
186         MockitoAnnotations.initMocks(this);
187         mInstrumentation = InstrumentationRegistry.getInstrumentation();
188         mTestableLooper = TestableLooper.get(this);
189         mTextView = new KeyguardIndicationTextView(mContext);
190         mTextView.setAnimationsEnabled(false);
191 
192         // TODO(b/259908270): remove
193         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
194                 DevicePolicyManager.ADD_ISFINANCED_DEVICE_FLAG, "true",
195                 /* makeDefault= */ false);
196         mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
197         mContext.addMockSystemService(UserManager.class, mUserManager);
198         mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
199         mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
200         mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
201                 ORGANIZATION_NAME);
202         mDisclosureGeneric = mContext.getString(R.string.do_disclosure_generic);
203         mFinancedDisclosureWithOrganization = mContext.getString(
204                 R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME);
205 
206         when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
207         when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
208         when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
209 
210         when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom))
211                 .thenReturn(mIndicationAreaBottom);
212         when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
213 
214         when(mDevicePolicyManager.getResources()).thenReturn(mDevicePolicyResourcesManager);
215         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
216                 .thenReturn(DEVICE_OWNER_COMPONENT);
217         when(mDevicePolicyManager.isFinancedDevice()).thenReturn(false);
218         // TODO(b/259908270): remove
219         when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
220                 .thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
221 
222         when(mDevicePolicyResourcesManager.getString(anyString(), any()))
223                 .thenReturn(mDisclosureGeneric);
224         when(mDevicePolicyResourcesManager.getString(anyString(), any(), anyString()))
225                 .thenReturn(mDisclosureWithOrganization);
226         when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
227 
228         mIndicationHelper = new IndicationHelper(mKeyguardUpdateMonitor);
229 
230         mWakeLock = new WakeLockFake();
231         mWakeLockBuilder = new WakeLockFake.Builder(mContext);
232         mWakeLockBuilder.setWakeLock(mWakeLock);
233     }
234 
235     @After
tearDown()236     public void tearDown() throws Exception {
237         mTextView.setAnimationsEnabled(true);
238         if (mController != null) {
239             mController.destroy();
240             mController = null;
241         }
242     }
243 
createController()244     protected void createController() {
245         if (Looper.myLooper() == null) {
246             Looper.prepare();
247         }
248 
249         mFlags = new FakeFeatureFlags();
250         mFlags.set(KEYGUARD_TALKBACK_FIX, true);
251         mFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
252         mFlags.set(FACE_AUTH_REFACTOR, false);
253         mController = new KeyguardIndicationController(
254                 mContext,
255                 mTestableLooper.getLooper(),
256                 mWakeLockBuilder,
257                 mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
258                 mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
259                 mUserManager, mExecutor, mExecutor, mFalsingManager,
260                 mAuthController, mLockPatternUtils, mScreenLifecycle,
261                 mKeyguardBypassController, mAccessibilityManager,
262                 mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
263                 mAlternateBouncerInteractor,
264                 mAlarmManager,
265                 mUserTracker,
266                 mock(BouncerMessageInteractor.class),
267                 mFlags,
268                 mIndicationHelper,
269                 KeyguardInteractorFactory.create(mFlags).getKeyguardInteractor()
270         );
271         mController.init();
272         mController.setIndicationArea(mIndicationArea);
273         verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
274         mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
275         verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(), any());
276         mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
277         mController.mRotateTextViewController = mRotateTextViewController;
278         mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
279         clearInvocations(mIBatteryStats);
280 
281         verify(mKeyguardStateController).addCallback(
282                 mKeyguardStateControllerCallbackCaptor.capture());
283         mKeyguardStateControllerCallback = mKeyguardStateControllerCallbackCaptor.getValue();
284 
285         verify(mKeyguardUpdateMonitor).registerCallback(
286                 mKeyguardUpdateMonitorCallbackCaptor.capture());
287         mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue();
288 
289         verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
290         mScreenObserver = mScreenObserverCaptor.getValue();
291 
292         mExecutor.runAllReady();
293         reset(mRotateTextViewController);
294     }
295 }
296