blob: daee55bd3d618bee54af8dcf2a3d489f8c2bc875 [file] [log] [blame]
Bartosz Fabianowski5f045002016-12-01 10:36:18 +01001/*
2 * Copyright (C) 2016 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
17package com.android.systemui.statusbar;
18
Lucas Dupinff6628d2018-10-15 10:12:37 -070019import static com.google.common.truth.Truth.assertThat;
20
Adrian Roosc1b50322017-02-27 21:07:58 +010021import static org.junit.Assert.assertFalse;
22import static org.junit.Assert.assertTrue;
Lucas Dupin8e2fd012019-04-25 16:40:54 -070023import static org.mockito.ArgumentMatchers.any;
Lucas Dupin0df60fe2019-04-23 10:19:27 -070024import static org.mockito.ArgumentMatchers.anyInt;
25import static org.mockito.ArgumentMatchers.eq;
Jason Monk3cfedd72016-12-09 09:31:37 -050026import static org.mockito.Mockito.mock;
27import static org.mockito.Mockito.reset;
Lucas Dupin8e2fd012019-04-25 16:40:54 -070028import static org.mockito.Mockito.times;
Jason Monk3cfedd72016-12-09 09:31:37 -050029import static org.mockito.Mockito.verify;
30import static org.mockito.Mockito.verifyNoMoreInteractions;
31import static org.mockito.Mockito.when;
32
Adrian Roosc1b50322017-02-27 21:07:58 +010033import android.app.Instrumentation;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010034import android.app.admin.DevicePolicyManager;
35import android.app.trust.TrustManager;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010036import android.content.Context;
Lucas Dupinff6628d2018-10-15 10:12:37 -070037import android.graphics.Color;
Jason Monk3cfedd72016-12-09 09:31:37 -050038import android.hardware.fingerprint.FingerprintManager;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010039import android.os.Looper;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010040import android.view.View;
41import android.view.ViewGroup;
42
Brett Chabot84151d92019-02-27 15:37:59 -080043import androidx.test.InstrumentationRegistry;
44import androidx.test.filters.SmallTest;
45import androidx.test.runner.AndroidJUnit4;
46
Lucas Dupin2e838ac2019-04-17 16:50:58 -070047import com.android.internal.widget.LockPatternUtils;
Lucas Dupin8e2fd012019-04-25 16:40:54 -070048import com.android.keyguard.KeyguardUpdateMonitor;
Adrian Roosaf45b602017-03-14 13:10:25 -070049import com.android.keyguard.KeyguardUpdateMonitorCallback;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010050import com.android.systemui.R;
51import com.android.systemui.SysuiTestCase;
Lucas Dupin8e2fd012019-04-25 16:40:54 -070052import com.android.systemui.plugins.statusbar.StatusBarStateController;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010053import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
Lucas Dupin2e838ac2019-04-17 16:50:58 -070054import com.android.systemui.statusbar.phone.LockIcon;
Lucas Dupin0df60fe2019-04-23 10:19:27 -070055import com.android.systemui.statusbar.phone.ShadeController;
Lucas Dupin8e2fd012019-04-25 16:40:54 -070056import com.android.systemui.statusbar.phone.UnlockMethodCache;
Lucas Dupin0df60fe2019-04-23 10:19:27 -070057import com.android.systemui.statusbar.policy.AccessibilityController;
Adrian Roosc1b50322017-02-27 21:07:58 +010058import com.android.systemui.util.wakelock.WakeLockFake;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010059
60import org.junit.Before;
61import org.junit.Test;
62import org.junit.runner.RunWith;
Lucas Dupin0df60fe2019-04-23 10:19:27 -070063import org.mockito.ArgumentCaptor;
Lucas Dupinff6628d2018-10-15 10:12:37 -070064import org.mockito.Mock;
65import org.mockito.MockitoAnnotations;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010066
67@SmallTest
68@RunWith(AndroidJUnit4.class)
69public class KeyguardIndicationControllerTest extends SysuiTestCase {
70
71 private final String ORGANIZATION_NAME = "organization";
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010072
Jason Monk3cfedd72016-12-09 09:31:37 -050073 private String mDisclosureWithOrganization;
74
Lucas Dupinff6628d2018-10-15 10:12:37 -070075 @Mock
76 private DevicePolicyManager mDevicePolicyManager;
77 @Mock
78 private ViewGroup mIndicationArea;
79 @Mock
80 private KeyguardIndicationTextView mDisclosure;
Lucas Dupin2e838ac2019-04-17 16:50:58 -070081 @Mock
82 private LockIcon mLockIcon;
83 @Mock
84 private LockPatternUtils mLockPatternUtils;
Lucas Dupin0df60fe2019-04-23 10:19:27 -070085 @Mock
86 private ShadeController mShadeController;
87 @Mock
88 private AccessibilityController mAccessibilityController;
Lucas Dupin8e2fd012019-04-25 16:40:54 -070089 @Mock
90 private UnlockMethodCache mUnlockMethodCache;
91 @Mock
92 private StatusBarStateController mStatusBarStateController;
93 @Mock
94 private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
Lucas Dupinff6628d2018-10-15 10:12:37 -070095 private KeyguardIndicationTextView mTextView;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +010096
97 private KeyguardIndicationController mController;
Adrian Roosc1b50322017-02-27 21:07:58 +010098 private WakeLockFake mWakeLock;
99 private Instrumentation mInstrumentation;
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100100
101 @Before
102 public void setUp() throws Exception {
Lucas Dupinff6628d2018-10-15 10:12:37 -0700103 MockitoAnnotations.initMocks(this);
Adrian Roosc1b50322017-02-27 21:07:58 +0100104 mInstrumentation = InstrumentationRegistry.getInstrumentation();
Lucas Dupinff6628d2018-10-15 10:12:37 -0700105 mTextView = new KeyguardIndicationTextView(mContext);
Adrian Roosc1b50322017-02-27 21:07:58 +0100106
Jason Monk3cfedd72016-12-09 09:31:37 -0500107 mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
108 mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
109 mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
110 mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
111 ORGANIZATION_NAME);
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100112
113 when(mIndicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure))
114 .thenReturn(mDisclosure);
Lucas Dupinff6628d2018-10-15 10:12:37 -0700115 when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
Adrian Roosc1b50322017-02-27 21:07:58 +0100116
117 mWakeLock = new WakeLockFake();
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100118 }
119
120 private void createController() {
121 if (Looper.myLooper() == null) {
122 Looper.prepare();
123 }
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700124 mController = new KeyguardIndicationController(mContext, mIndicationArea, mLockIcon,
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700125 mLockPatternUtils, mWakeLock, mShadeController, mAccessibilityController,
126 mUnlockMethodCache, mStatusBarStateController, mKeyguardUpdateMonitor);
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100127 }
128
129 @Test
130 public void unmanaged() {
131 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
132 createController();
133
134 verify(mDisclosure).setVisibility(View.GONE);
135 verifyNoMoreInteractions(mDisclosure);
136 }
137
138 @Test
139 public void managedNoOwnerName() {
140 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
141 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
142 createController();
143
144 verify(mDisclosure).setVisibility(View.VISIBLE);
145 verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
146 verifyNoMoreInteractions(mDisclosure);
147 }
148
149 @Test
150 public void managedOwnerName() {
151 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
152 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
153 createController();
154
155 verify(mDisclosure).setVisibility(View.VISIBLE);
Jason Monk3cfedd72016-12-09 09:31:37 -0500156 verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100157 verifyNoMoreInteractions(mDisclosure);
158 }
159
160 @Test
161 public void updateOnTheFly() {
162 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
163 createController();
164
Adrian Roosaf45b602017-03-14 13:10:25 -0700165 final KeyguardUpdateMonitorCallback monitor = mController.getKeyguardCallback();
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100166 reset(mDisclosure);
167
168 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
169 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
170 monitor.onKeyguardVisibilityChanged(true);
171
172 verify(mDisclosure).setVisibility(View.VISIBLE);
173 verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
174 verifyNoMoreInteractions(mDisclosure);
175 reset(mDisclosure);
176
177 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
178 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
179 monitor.onKeyguardVisibilityChanged(false);
180 monitor.onKeyguardVisibilityChanged(true);
181
182 verify(mDisclosure).setVisibility(View.VISIBLE);
Jason Monk3cfedd72016-12-09 09:31:37 -0500183 verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100184 verifyNoMoreInteractions(mDisclosure);
185 reset(mDisclosure);
186
187 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
188 monitor.onKeyguardVisibilityChanged(false);
189 monitor.onKeyguardVisibilityChanged(true);
190
191 verify(mDisclosure).setVisibility(View.GONE);
192 verifyNoMoreInteractions(mDisclosure);
193 }
Adrian Roosc1b50322017-02-27 21:07:58 +0100194
195 @Test
196 public void transientIndication_holdsWakeLock_whenDozing() {
197 createController();
198
199 mController.setDozing(true);
200 mController.showTransientIndication("Test");
201
202 assertTrue(mWakeLock.isHeld());
203 }
204
205 @Test
206 public void transientIndication_releasesWakeLock_afterHiding() {
207 createController();
208
209 mController.setDozing(true);
210 mController.showTransientIndication("Test");
211 mController.hideTransientIndication();
212
213 assertFalse(mWakeLock.isHeld());
214 }
215
216 @Test
217 public void transientIndication_releasesWakeLock_afterHidingDelayed() throws Throwable {
218 mInstrumentation.runOnMainSync(() -> {
219 createController();
220
221 mController.setDozing(true);
222 mController.showTransientIndication("Test");
223 mController.hideTransientIndicationDelayed(0);
224 });
225 mInstrumentation.waitForIdleSync();
226
Adrian Roosaf45b602017-03-14 13:10:25 -0700227 Boolean[] held = new Boolean[1];
Adrian Roosc1b50322017-02-27 21:07:58 +0100228 mInstrumentation.runOnMainSync(() -> {
229 held[0] = mWakeLock.isHeld();
Adrian Roosc1b50322017-02-27 21:07:58 +0100230 });
Adrian Roosaf45b602017-03-14 13:10:25 -0700231 assertFalse("WakeLock expected: RELEASED, was: HELD", held[0]);
Adrian Roosc1b50322017-02-27 21:07:58 +0100232 }
Lucas Dupinff6628d2018-10-15 10:12:37 -0700233
234 @Test
235 public void transientIndication_visibleWhenDozing() {
236 createController();
237
238 mController.setVisible(true);
239 mController.showTransientIndication("Test");
240 mController.setDozing(true);
241
242 assertThat(mTextView.getText()).isEqualTo("Test");
243 assertThat(mTextView.getCurrentTextColor()).isEqualTo(Color.WHITE);
244 assertThat(mTextView.getAlpha()).isEqualTo(1f);
245 }
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700246
247 @Test
248 public void lockIcon_click() {
249 createController();
250
251 ArgumentCaptor<View.OnLongClickListener> longClickCaptor = ArgumentCaptor.forClass(
252 View.OnLongClickListener.class);
253 ArgumentCaptor<View.OnClickListener> clickCaptor = ArgumentCaptor.forClass(
254 View.OnClickListener.class);
255 verify(mLockIcon).setOnLongClickListener(longClickCaptor.capture());
256 verify(mLockIcon).setOnClickListener(clickCaptor.capture());
257
258 when(mAccessibilityController.isAccessibilityEnabled()).thenReturn(true);
259 clickCaptor.getValue().onClick(mLockIcon);
Lucas Dupind54f00e2019-05-06 17:44:03 -0700260 verify(mShadeController).animateCollapsePanels(anyInt(), eq(true));
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700261
262 longClickCaptor.getValue().onLongClick(mLockIcon);
263 verify(mLockPatternUtils).requireCredentialEntry(anyInt());
Lucas Dupinca88e5f2019-05-14 16:11:08 -0700264 verify(mKeyguardUpdateMonitor).onLockIconPressed();
Lucas Dupin0df60fe2019-04-23 10:19:27 -0700265 }
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700266
267 @Test
268 public void unlockMethodCache_listenerUpdatesIndication() {
269 createController();
270 String restingIndication = "Resting indication";
271 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
272 mController.setRestingIndication(restingIndication);
273 mController.setVisible(true);
274 assertThat(mTextView.getText()).isEqualTo(mController.getTrustGrantedIndication());
275
276 reset(mKeyguardUpdateMonitor);
277 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
278 mController.onUnlockMethodStateChanged();
279 assertThat(mTextView.getText()).isEqualTo(restingIndication);
280 }
281
282 @Test
283 public void unlockMethodCache_listener() {
284 createController();
285 verify(mUnlockMethodCache).addListener(eq(mController));
286 verify(mStatusBarStateController).addCallback(eq(mController));
287 verify(mKeyguardUpdateMonitor, times(2)).registerCallback(any());
Lucas Dupin8e2fd012019-04-25 16:40:54 -0700288 }
Bartosz Fabianowski5f045002016-12-01 10:36:18 +0100289}