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