• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.server.wm;
18 
19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
20 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
21 import static android.server.wm.CliIntentExtra.extraString;
22 import static android.server.wm.MockImeHelper.createManagedMockImeSession;
23 import static android.server.wm.UiDeviceUtils.pressBackButton;
24 import static android.server.wm.app.Components.DISMISS_KEYGUARD_ACTIVITY;
25 import static android.server.wm.app.Components.DISMISS_KEYGUARD_METHOD_ACTIVITY;
26 import static android.server.wm.app.Components.PIP_ACTIVITY;
27 import static android.server.wm.app.Components.PipActivity.ACTION_ENTER_PIP;
28 import static android.server.wm.app.Components.PipActivity.EXTRA_DISMISS_KEYGUARD;
29 import static android.server.wm.app.Components.PipActivity.EXTRA_ENTER_PIP;
30 import static android.server.wm.app.Components.PipActivity.EXTRA_SHOW_OVER_KEYGUARD;
31 import static android.server.wm.app.Components.SHOW_WHEN_LOCKED_ACTIVITY;
32 import static android.server.wm.app.Components.SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY;
33 import static android.server.wm.app.Components.TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY;
34 import static android.view.Display.DEFAULT_DISPLAY;
35 import static android.view.WindowInsets.Type.ime;
36 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
37 
38 import static androidx.test.InstrumentationRegistry.getInstrumentation;
39 
40 import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
41 
42 import static org.junit.Assert.assertFalse;
43 import static org.junit.Assert.assertTrue;
44 import static org.junit.Assume.assumeFalse;
45 import static org.junit.Assume.assumeTrue;
46 
47 import android.app.Activity;
48 import android.app.KeyguardManager;
49 import android.content.ComponentName;
50 import android.os.Bundle;
51 import android.os.SystemClock;
52 import android.platform.test.annotations.Presubmit;
53 import android.view.View;
54 import android.widget.EditText;
55 import android.widget.LinearLayout;
56 
57 import androidx.test.InstrumentationRegistry;
58 
59 import com.android.compatibility.common.util.CtsTouchUtils;
60 import com.android.compatibility.common.util.PollingCheck;
61 import com.android.cts.mockime.ImeEventStream;
62 import com.android.cts.mockime.MockImeSession;
63 
64 import org.junit.Before;
65 import org.junit.Test;
66 
67 import java.util.concurrent.TimeUnit;
68 
69 /**
70  * Build/Install/Run:
71  *     atest CtsWindowManagerDeviceTestCases:KeyguardLockedTests
72  */
73 @Presubmit
74 @android.server.wm.annotation.Group2
75 public class KeyguardLockedTests extends KeyguardTestBase {
76 
77     private final static long TIMEOUT_IME = TimeUnit.SECONDS.toMillis(5);
78 
79     private final CtsTouchUtils mCtsTouchUtils =
80             new CtsTouchUtils(InstrumentationRegistry.getTargetContext());
81 
82     @Before
83     @Override
setUp()84     public void setUp() throws Exception {
85         super.setUp();
86         assumeTrue(supportsSecureLock());
87     }
88 
89     @Test
testLockAndUnlock()90     public void testLockAndUnlock() {
91         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
92         lockScreenSession.setLockCredential().gotoKeyguard();
93 
94         assertTrue(mKeyguardManager.isKeyguardLocked());
95         assertTrue(mKeyguardManager.isDeviceLocked());
96         assertTrue(mKeyguardManager.isDeviceSecure());
97         assertTrue(mKeyguardManager.isKeyguardSecure());
98         mWmState.assertKeyguardShowingAndNotOccluded();
99 
100         lockScreenSession.unlockDevice().enterAndConfirmLockCredential();
101 
102         mWmState.waitAndAssertKeyguardGone();
103         assertFalse(mKeyguardManager.isDeviceLocked());
104         assertFalse(mKeyguardManager.isKeyguardLocked());
105     }
106 
107     @Test
testDisableKeyguard_thenSettingCredential_reenablesKeyguard_b119322269()108     public void testDisableKeyguard_thenSettingCredential_reenablesKeyguard_b119322269() {
109         final KeyguardManager.KeyguardLock keyguardLock = mContext.getSystemService(
110                 KeyguardManager.class).newKeyguardLock("KeyguardLockedTests");
111 
112         try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
113             lockScreenSession.gotoKeyguard();
114             keyguardLock.disableKeyguard();
115 
116             lockScreenSession.setLockCredential();
117             lockScreenSession.gotoKeyguard();
118 
119             mWmState.waitForKeyguardShowingAndNotOccluded();
120             mWmState.assertKeyguardShowingAndNotOccluded();
121             assertTrue(mKeyguardManager.isKeyguardLocked());
122             assertTrue(mKeyguardManager.isDeviceLocked());
123             assertTrue(mKeyguardManager.isDeviceSecure());
124             assertTrue(mKeyguardManager.isKeyguardSecure());
125         } finally {
126             keyguardLock.reenableKeyguard();
127         }
128     }
129 
130     @Test
testDismissKeyguard()131     public void testDismissKeyguard() {
132         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
133         lockScreenSession.setLockCredential().gotoKeyguard();
134 
135         mWmState.assertKeyguardShowingAndNotOccluded();
136         launchActivity(DISMISS_KEYGUARD_ACTIVITY);
137         lockScreenSession.enterAndConfirmLockCredential();
138 
139         mWmState.waitAndAssertKeyguardGone();
140         mWmState.assertVisibility(DISMISS_KEYGUARD_ACTIVITY, true);
141     }
142 
143     @Test
testDismissKeyguard_whileOccluded()144     public void testDismissKeyguard_whileOccluded() {
145         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
146         lockScreenSession.setLockCredential().gotoKeyguard();
147 
148         mWmState.assertKeyguardShowingAndNotOccluded();
149         launchActivity(SHOW_WHEN_LOCKED_ACTIVITY);
150         mWmState.computeState(SHOW_WHEN_LOCKED_ACTIVITY);
151         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
152 
153         launchActivity(DISMISS_KEYGUARD_ACTIVITY);
154         lockScreenSession.enterAndConfirmLockCredential();
155         mWmState.waitAndAssertKeyguardGone();
156         mWmState.computeState(DISMISS_KEYGUARD_ACTIVITY);
157 
158         final boolean isDismissTranslucent = mWmState
159                 .isActivityTranslucent(DISMISS_KEYGUARD_ACTIVITY);
160         mWmState.assertVisibility(DISMISS_KEYGUARD_ACTIVITY, true);
161         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, isDismissTranslucent);
162     }
163 
164     @Test
testDismissKeyguard_fromShowWhenLocked_notAllowed()165     public void testDismissKeyguard_fromShowWhenLocked_notAllowed() {
166         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
167         lockScreenSession.setLockCredential().gotoKeyguard();
168 
169         mWmState.assertKeyguardShowingAndNotOccluded();
170         launchActivity(SHOW_WHEN_LOCKED_ACTIVITY);
171         mWmState.computeState(SHOW_WHEN_LOCKED_ACTIVITY);
172         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
173         mBroadcastActionTrigger.dismissKeyguardByFlag();
174         lockScreenSession.enterAndConfirmLockCredential();
175 
176         // Make sure we stay on Keyguard.
177         mWmState.assertKeyguardShowingAndOccluded();
178         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
179     }
180 
181     @Test
testDismissKeyguardActivity_method()182     public void testDismissKeyguardActivity_method() {
183         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
184         lockScreenSession.setLockCredential();
185         separateTestJournal();
186 
187         lockScreenSession.gotoKeyguard();
188         mWmState.computeState();
189         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
190 
191         launchActivity(DISMISS_KEYGUARD_METHOD_ACTIVITY);
192         lockScreenSession.enterAndConfirmLockCredential();
193         mWmState.waitForKeyguardGone();
194         mWmState.computeState(DISMISS_KEYGUARD_METHOD_ACTIVITY);
195         mWmState.assertVisibility(DISMISS_KEYGUARD_METHOD_ACTIVITY, true);
196         assertFalse(mWmState.getKeyguardControllerState().keyguardShowing);
197         assertOnDismissSucceeded(DISMISS_KEYGUARD_METHOD_ACTIVITY);
198     }
199 
200     @Test
testDismissKeyguardActivity_method_cancelled()201     public void testDismissKeyguardActivity_method_cancelled() {
202         // Pressing the back button does not cancel Keyguard in AAOS.
203         assumeFalse(isCar());
204 
205         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
206         lockScreenSession.setLockCredential();
207         separateTestJournal();
208 
209         lockScreenSession.gotoKeyguard();
210         mWmState.computeState();
211         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
212 
213         launchActivity(DISMISS_KEYGUARD_METHOD_ACTIVITY);
214         pressBackButton();
215         assertOnDismissCancelled(DISMISS_KEYGUARD_METHOD_ACTIVITY);
216         mWmState.computeState();
217         mWmState.assertVisibility(DISMISS_KEYGUARD_METHOD_ACTIVITY, false);
218         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
219     }
220 
221     @Test
testDismissKeyguardAttrActivity_method_turnScreenOn_withSecureKeyguard()222     public void testDismissKeyguardAttrActivity_method_turnScreenOn_withSecureKeyguard() {
223         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
224         lockScreenSession.setLockCredential().sleepDevice();
225         mWmState.computeState();
226         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
227 
228         launchActivity(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY);
229         mWmState.waitForKeyguardShowingAndNotOccluded();
230         mWmState.assertVisibility(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY, false);
231         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
232         assertTrue(isDisplayOn(DEFAULT_DISPLAY));
233     }
234 
235     @Test
testEnterPipOverKeyguard()236     public void testEnterPipOverKeyguard() {
237         assumeTrue(supportsPip());
238 
239         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
240         lockScreenSession.setLockCredential();
241 
242         // Show the PiP activity in fullscreen.
243         launchActivity(PIP_ACTIVITY, extraString(EXTRA_SHOW_OVER_KEYGUARD, "true"));
244 
245         // Lock the screen and ensure that the PiP activity showing over the LockScreen.
246         lockScreenSession.gotoKeyguard(PIP_ACTIVITY);
247         mWmState.waitForKeyguardShowingAndOccluded();
248         mWmState.assertKeyguardShowingAndOccluded();
249 
250         // Request that the PiP activity enter picture-in-picture mode (ensure it does not).
251         mBroadcastActionTrigger.doAction(ACTION_ENTER_PIP);
252         waitForEnterPip(PIP_ACTIVITY);
253         mWmState.assertDoesNotContainStack("Must not contain pinned stack.",
254                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
255 
256         // Enter the credentials and ensure that the activity actually entered picture-in-picture.
257         lockScreenSession.enterAndConfirmLockCredential();
258         mWmState.waitAndAssertKeyguardGone();
259         waitForEnterPip(PIP_ACTIVITY);
260         mWmState.assertContainsStack("Must contain pinned stack.", WINDOWING_MODE_PINNED,
261                 ACTIVITY_TYPE_STANDARD);
262     }
263 
264     @Test
testShowWhenLockedActivityAndPipActivity()265     public void testShowWhenLockedActivityAndPipActivity() {
266         assumeTrue(supportsPip());
267 
268         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
269         lockScreenSession.setLockCredential();
270 
271         // Show an activity in PIP.
272         launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"));
273         waitForEnterPip(PIP_ACTIVITY);
274         mWmState.assertContainsStack("Must contain pinned stack.", WINDOWING_MODE_PINNED,
275                 ACTIVITY_TYPE_STANDARD);
276         mWmState.assertVisibility(PIP_ACTIVITY, true);
277 
278         // Show an activity that will keep above the keyguard.
279         launchActivity(SHOW_WHEN_LOCKED_ACTIVITY);
280         mWmState.computeState(SHOW_WHEN_LOCKED_ACTIVITY);
281         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
282 
283         // Lock the screen and ensure that the fullscreen activity showing over the lockscreen
284         // is visible, but not the PiP activity.
285         lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_ACTIVITY);
286         mWmState.computeState();
287         mWmState.assertKeyguardShowingAndOccluded();
288         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
289         mWmState.assertVisibility(PIP_ACTIVITY, false);
290     }
291 
292     @Test
testShowWhenLockedPipActivity()293     public void testShowWhenLockedPipActivity() {
294         assumeTrue(supportsPip());
295 
296         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
297         lockScreenSession.setLockCredential();
298 
299         // Show an activity in PIP.
300         launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"),
301                 extraString(EXTRA_SHOW_OVER_KEYGUARD, "true"));
302         waitForEnterPip(PIP_ACTIVITY);
303         mWmState.assertContainsStack("Must contain pinned stack.", WINDOWING_MODE_PINNED,
304                 ACTIVITY_TYPE_STANDARD);
305         mWmState.assertVisibility(PIP_ACTIVITY, true);
306 
307         // Lock the screen and ensure the PiP activity is not visible on the lockscreen even
308         // though it's marked as showing over the lockscreen itself.
309         lockScreenSession.gotoKeyguard();
310         mWmState.assertKeyguardShowingAndNotOccluded();
311         mWmState.assertVisibility(PIP_ACTIVITY, false);
312     }
313 
314     @Test
testDismissKeyguardPipActivity()315     public void testDismissKeyguardPipActivity() {
316         assumeTrue(supportsPip());
317 
318         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
319         // Show an activity in PIP.
320         launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"),
321                 extraString(EXTRA_DISMISS_KEYGUARD, "true"));
322         waitForEnterPip(PIP_ACTIVITY);
323         mWmState.assertContainsStack("Must contain pinned stack.", WINDOWING_MODE_PINNED,
324                 ACTIVITY_TYPE_STANDARD);
325         mWmState.assertVisibility(PIP_ACTIVITY, true);
326 
327         // Lock the screen and ensure the PiP activity is not visible on the lockscreen even
328         // though it's marked as dismiss keyguard.
329         lockScreenSession.gotoKeyguard();
330         mWmState.computeState();
331         mWmState.assertKeyguardShowingAndNotOccluded();
332         mWmState.assertVisibility(PIP_ACTIVITY, false);
333     }
334 
335     @Test
testShowWhenLockedAttrImeActivityAndShowSoftInput()336     public void testShowWhenLockedAttrImeActivityAndShowSoftInput() throws Exception {
337         assumeTrue(MSG_NO_MOCK_IME, supportsInstallableIme());
338 
339         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
340         final MockImeSession mockImeSession = createManagedMockImeSession(this);
341 
342         lockScreenSession.setLockCredential().gotoKeyguard();
343         mWmState.assertKeyguardShowingAndNotOccluded();
344         launchActivity(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
345         mWmState.computeState(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
346         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY, true);
347 
348         // Make sure the activity has been called showSoftInput & IME window is visible.
349         final ImeEventStream stream = mockImeSession.openEventStream();
350         expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
351                 TIMEOUT_IME);
352         // Assert the IME is shown on the expected display.
353         mWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
354     }
355 
356     @Test
testShowWhenLockedImeActivityAndShowSoftInput()357     public void testShowWhenLockedImeActivityAndShowSoftInput() throws Exception {
358         assumeTrue(MSG_NO_MOCK_IME, supportsInstallableIme());
359 
360         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
361         final MockImeSession mockImeSession = createManagedMockImeSession(this);
362         final TestActivitySession<ShowWhenLockedImeActivity> imeTestActivitySession =
363                 createManagedTestActivitySession();
364 
365         lockScreenSession.setLockCredential().gotoKeyguard();
366         mWmState.assertKeyguardShowingAndNotOccluded();
367         imeTestActivitySession.launchTestActivityOnDisplaySync(ShowWhenLockedImeActivity.class,
368                 DEFAULT_DISPLAY);
369 
370         // Make sure the activity has been called showSoftInput & IME window is visible.
371         final ImeEventStream stream = mockImeSession.openEventStream();
372         expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
373                 TIMEOUT_IME);
374         // Assert the IME is shown on the expected display.
375         mWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
376 
377     }
378 
379     @Test
testImeShowsAfterLockScreenOnEditorTap()380     public void testImeShowsAfterLockScreenOnEditorTap() throws Exception {
381         assumeTrue(MSG_NO_MOCK_IME, supportsInstallableIme());
382 
383         final MockImeSession mockImeSession = createManagedMockImeSession(this);
384         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
385         final TestActivitySession<ShowImeAfterLockscreenActivity> imeTestActivitySession =
386                 createManagedTestActivitySession();
387         imeTestActivitySession.launchTestActivityOnDisplaySync(ShowImeAfterLockscreenActivity.class,
388                 DEFAULT_DISPLAY);
389 
390         final ShowImeAfterLockscreenActivity activity = imeTestActivitySession.getActivity();
391         final View rootView = activity.getWindow().getDecorView();
392 
393         mCtsTouchUtils.emulateTapOnViewCenter(getInstrumentation(), null, activity.mEditor);
394         PollingCheck.waitFor(
395                 TIMEOUT_IME,
396                 () -> rootView.getRootWindowInsets().isVisible(ime()));
397 
398         lockScreenSession.setLockCredential().gotoKeyguard();
399         assertTrue("Keyguard is showing", mWmState.getKeyguardControllerState().keyguardShowing);
400         lockScreenSession.unlockDevice().enterAndConfirmLockCredential();
401         mWmState.waitAndAssertKeyguardGone();
402 
403         final ImeEventStream stream = mockImeSession.openEventStream();
404 
405         mCtsTouchUtils.emulateTapOnViewCenter(getInstrumentation(), null, activity.mEditor);
406 
407         // Make sure the activity has been called showSoftInput & IME window is visible.
408         expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
409                 TimeUnit.SECONDS.toMillis(5) /* eventTimeout */);
410         // Assert the IME is shown event on the expected display.
411         mWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
412         // Check if IME is actually visible.
413         PollingCheck.waitFor(
414                 TIMEOUT_IME,
415                 () -> rootView.getRootWindowInsets().isVisible(ime()));
416     }
417 
418     public static class ShowImeAfterLockscreenActivity extends Activity {
419 
420         EditText mEditor;
421 
422         @Override
onCreate(Bundle icicle)423         protected void onCreate(Bundle icicle) {
424             super.onCreate(icicle);
425             mEditor = createViews(this, false /* showWhenLocked */);
426         }
427     }
428 
429     public static class ShowWhenLockedImeActivity extends Activity {
430 
431         @Override
onCreate(Bundle icicle)432         protected void onCreate(Bundle icicle) {
433             super.onCreate(icicle);
434             createViews(this, true /* showWhenLocked */);
435         }
436     }
437 
createViews( Activity activity, boolean showWhenLocked )438     private static EditText createViews(
439             Activity activity, boolean showWhenLocked /* showWhenLocked */) {
440         EditText editor = new EditText(activity);
441         // Set private IME option for editorMatcher to identify which TextView received
442         // onStartInput event.
443         editor.setPrivateImeOptions(
444                 activity.getClass().getName()
445                         + "/" + Long.toString(SystemClock.elapsedRealtimeNanos()));
446         final LinearLayout layout = new LinearLayout(activity);
447         layout.setOrientation(LinearLayout.VERTICAL);
448         layout.addView(editor);
449         activity.setContentView(layout);
450 
451         if (showWhenLocked) {
452             // Set showWhenLocked as true & request focus for showing soft input.
453             activity.setShowWhenLocked(true);
454             activity.getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
455         }
456         editor.requestFocus();
457         return editor;
458     }
459 
460     /**
461      * Waits until the given activity has entered picture-in-picture mode (allowing for the
462      * subsequent animation to start).
463      */
waitForEnterPip(ComponentName activityName)464     private void waitForEnterPip(ComponentName activityName) {
465         mWmState.waitForValidState(new WaitForValidActivityState.Builder(activityName)
466                 .setWindowingMode(WINDOWING_MODE_PINNED)
467                 .setActivityType(ACTIVITY_TYPE_STANDARD)
468                 .build());
469     }
470 }
471