• 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_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
testTurnScreenOnActivity_withSecureKeyguardAndAod()219     public void testTurnScreenOnActivity_withSecureKeyguardAndAod() {
220         final AodSession aodSession = createManagedAodSession();
221         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
222         lockScreenSession.setLockCredential();
223         testTurnScreenOnActivity_withSecureKeyguard(aodSession, lockScreenSession,
224                 false /* enableAod */);
225         testTurnScreenOnActivity_withSecureKeyguard(aodSession, lockScreenSession,
226                 true /* enableAod */);
227     }
228 
testTurnScreenOnActivity_withSecureKeyguard(AodSession aodSession, LockScreenSession lockScreenSession, boolean enableAod)229     private void testTurnScreenOnActivity_withSecureKeyguard(AodSession aodSession,
230             LockScreenSession lockScreenSession, boolean enableAod) {
231         if (enableAod) {
232             assumeTrue(aodSession.isAodAvailable());
233         }
234         aodSession.setAodEnabled(enableAod);
235         lockScreenSession.sleepDevice();
236         mWmState.computeState();
237         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
238 
239         final CommandSession.ActivitySessionClient activityClient =
240                 createManagedActivityClientSession();
241         final CommandSession.ActivitySession activity = activityClient.startActivity(
242                 getLaunchActivityBuilder().setUseInstrumentation().setIntentExtra(extra -> {
243                     extra.putBoolean(Components.TurnScreenOnActivity.EXTRA_SHOW_WHEN_LOCKED, false);
244                 }).setTargetActivity(TURN_SCREEN_ON_ACTIVITY));
245         mWmState.waitForKeyguardShowingAndNotOccluded();
246         mWmState.assertVisibility(TURN_SCREEN_ON_ACTIVITY, false);
247         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
248         assertFalse(isDisplayOn(DEFAULT_DISPLAY));
249         activity.finish();
250     }
251 
252     @Test
testDismissKeyguardAttrActivity_method_turnScreenOn_withSecureKeyguard()253     public void testDismissKeyguardAttrActivity_method_turnScreenOn_withSecureKeyguard() {
254         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
255         lockScreenSession.setLockCredential().sleepDevice();
256         mWmState.computeState();
257         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
258 
259         launchActivity(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY);
260         mWmState.waitForKeyguardShowingAndNotOccluded();
261         mWmState.assertVisibility(TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY, false);
262         assertTrue(mWmState.getKeyguardControllerState().keyguardShowing);
263         assertTrue(isDisplayOn(DEFAULT_DISPLAY));
264     }
265 
266     @Test
testEnterPipOverKeyguard()267     public void testEnterPipOverKeyguard() {
268         assumeTrue(supportsPip());
269 
270         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
271         lockScreenSession.setLockCredential();
272 
273         // Show the PiP activity in fullscreen.
274         launchActivity(PIP_ACTIVITY, extraString(EXTRA_SHOW_OVER_KEYGUARD, "true"));
275 
276         // Lock the screen and ensure that the PiP activity showing over the LockScreen.
277         lockScreenSession.gotoKeyguard(PIP_ACTIVITY);
278         mWmState.waitForKeyguardShowingAndOccluded();
279         mWmState.assertKeyguardShowingAndOccluded();
280 
281         // Request that the PiP activity enter picture-in-picture mode (ensure it does not).
282         mBroadcastActionTrigger.doAction(ACTION_ENTER_PIP);
283         waitForEnterPip(PIP_ACTIVITY);
284         mWmState.assertDoesNotContainStack("Must not contain pinned stack.",
285                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
286 
287         // Enter the credentials and ensure that the activity actually entered picture-in-picture.
288         lockScreenSession.enterAndConfirmLockCredential();
289         mWmState.waitAndAssertKeyguardGone();
290         waitForEnterPip(PIP_ACTIVITY);
291         mWmState.assertContainsStack("Must contain pinned stack.", WINDOWING_MODE_PINNED,
292                 ACTIVITY_TYPE_STANDARD);
293     }
294 
295     @Test
testShowWhenLockedActivityAndPipActivity()296     public void testShowWhenLockedActivityAndPipActivity() {
297         assumeTrue(supportsPip());
298 
299         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
300         lockScreenSession.setLockCredential();
301 
302         // Show an activity in PIP.
303         launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"));
304         waitForEnterPip(PIP_ACTIVITY);
305         mWmState.assertContainsStack("Must contain pinned stack.", WINDOWING_MODE_PINNED,
306                 ACTIVITY_TYPE_STANDARD);
307         mWmState.assertVisibility(PIP_ACTIVITY, true);
308 
309         // Show an activity that will keep above the keyguard.
310         launchActivity(SHOW_WHEN_LOCKED_ACTIVITY);
311         mWmState.computeState(SHOW_WHEN_LOCKED_ACTIVITY);
312         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
313 
314         // Lock the screen and ensure that the fullscreen activity showing over the lockscreen
315         // is visible, but not the PiP activity.
316         lockScreenSession.gotoKeyguard(SHOW_WHEN_LOCKED_ACTIVITY);
317         mWmState.computeState();
318         mWmState.assertKeyguardShowingAndOccluded();
319         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ACTIVITY, true);
320         mWmState.assertVisibility(PIP_ACTIVITY, false);
321     }
322 
323     @Test
testShowWhenLockedPipActivity()324     public void testShowWhenLockedPipActivity() {
325         assumeTrue(supportsPip());
326 
327         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
328         lockScreenSession.setLockCredential();
329 
330         // Show an activity in PIP.
331         launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"),
332                 extraString(EXTRA_SHOW_OVER_KEYGUARD, "true"));
333         waitForEnterPip(PIP_ACTIVITY);
334         mWmState.assertContainsStack("Must contain pinned stack.", WINDOWING_MODE_PINNED,
335                 ACTIVITY_TYPE_STANDARD);
336         mWmState.assertVisibility(PIP_ACTIVITY, true);
337 
338         // Lock the screen and ensure the PiP activity is not visible on the lockscreen even
339         // though it's marked as showing over the lockscreen itself.
340         lockScreenSession.gotoKeyguard();
341         mWmState.assertKeyguardShowingAndNotOccluded();
342         mWmState.assertVisibility(PIP_ACTIVITY, false);
343     }
344 
345     @Test
testDismissKeyguardPipActivity()346     public void testDismissKeyguardPipActivity() {
347         assumeTrue(supportsPip());
348 
349         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
350         // Show an activity in PIP.
351         launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"),
352                 extraString(EXTRA_DISMISS_KEYGUARD, "true"));
353         waitForEnterPip(PIP_ACTIVITY);
354         mWmState.assertContainsStack("Must contain pinned stack.", WINDOWING_MODE_PINNED,
355                 ACTIVITY_TYPE_STANDARD);
356         mWmState.assertVisibility(PIP_ACTIVITY, true);
357 
358         // Lock the screen and ensure the PiP activity is not visible on the lockscreen even
359         // though it's marked as dismiss keyguard.
360         lockScreenSession.gotoKeyguard();
361         mWmState.computeState();
362         mWmState.assertKeyguardShowingAndNotOccluded();
363         mWmState.assertVisibility(PIP_ACTIVITY, false);
364     }
365 
366     @Test
testShowWhenLockedAttrImeActivityAndShowSoftInput()367     public void testShowWhenLockedAttrImeActivityAndShowSoftInput() throws Exception {
368         assumeTrue(MSG_NO_MOCK_IME, supportsInstallableIme());
369 
370         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
371         final MockImeSession mockImeSession = createManagedMockImeSession(this);
372 
373         lockScreenSession.setLockCredential().gotoKeyguard();
374         mWmState.assertKeyguardShowingAndNotOccluded();
375         launchActivity(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
376         mWmState.computeState(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
377         mWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY, true);
378 
379         // Make sure the activity has been called showSoftInput & IME window is visible.
380         final ImeEventStream stream = mockImeSession.openEventStream();
381         expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
382                 TIMEOUT_IME);
383         // Assert the IME is shown on the expected display.
384         mWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
385     }
386 
387     @Test
testShowWhenLockedImeActivityAndShowSoftInput()388     public void testShowWhenLockedImeActivityAndShowSoftInput() throws Exception {
389         assumeTrue(MSG_NO_MOCK_IME, supportsInstallableIme());
390 
391         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
392         final MockImeSession mockImeSession = createManagedMockImeSession(this);
393         final TestActivitySession<ShowWhenLockedImeActivity> imeTestActivitySession =
394                 createManagedTestActivitySession();
395 
396         lockScreenSession.setLockCredential().gotoKeyguard();
397         mWmState.assertKeyguardShowingAndNotOccluded();
398         imeTestActivitySession.launchTestActivityOnDisplaySync(ShowWhenLockedImeActivity.class,
399                 DEFAULT_DISPLAY);
400 
401         // Make sure the activity has been called showSoftInput & IME window is visible.
402         final ImeEventStream stream = mockImeSession.openEventStream();
403         expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
404                 TIMEOUT_IME);
405         // Assert the IME is shown on the expected display.
406         mWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
407 
408     }
409 
410     @Test
testImeShowsAfterLockScreenOnEditorTap()411     public void testImeShowsAfterLockScreenOnEditorTap() throws Exception {
412         assumeTrue(MSG_NO_MOCK_IME, supportsInstallableIme());
413 
414         final MockImeSession mockImeSession = createManagedMockImeSession(this);
415         final LockScreenSession lockScreenSession = createManagedLockScreenSession();
416         final TestActivitySession<ShowImeAfterLockscreenActivity> imeTestActivitySession =
417                 createManagedTestActivitySession();
418         imeTestActivitySession.launchTestActivityOnDisplaySync(ShowImeAfterLockscreenActivity.class,
419                 DEFAULT_DISPLAY);
420 
421         final ShowImeAfterLockscreenActivity activity = imeTestActivitySession.getActivity();
422         final View rootView = activity.getWindow().getDecorView();
423 
424         CtsTouchUtils.emulateTapOnViewCenter(getInstrumentation(), null, activity.mEditor);
425         PollingCheck.waitFor(
426                 TIMEOUT_IME,
427                 () -> rootView.getRootWindowInsets().isVisible(ime()));
428 
429         lockScreenSession.setLockCredential().gotoKeyguard();
430         assertTrue("Keyguard is showing", mWmState.getKeyguardControllerState().keyguardShowing);
431         lockScreenSession.enterAndConfirmLockCredential();
432         mWmState.waitAndAssertKeyguardGone();
433 
434         final ImeEventStream stream = mockImeSession.openEventStream();
435 
436         CtsTouchUtils.emulateTapOnViewCenter(getInstrumentation(), null, activity.mEditor);
437 
438         // Make sure the activity has been called showSoftInput & IME window is visible.
439         expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
440                 TimeUnit.SECONDS.toMillis(5) /* eventTimeout */);
441         // Assert the IME is shown event on the expected display.
442         mWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
443         // Check if IME is actually visible.
444         PollingCheck.waitFor(
445                 TIMEOUT_IME,
446                 () -> rootView.getRootWindowInsets().isVisible(ime()));
447     }
448 
449     public static class ShowImeAfterLockscreenActivity extends Activity {
450 
451         EditText mEditor;
452 
453         @Override
onCreate(Bundle icicle)454         protected void onCreate(Bundle icicle) {
455             super.onCreate(icicle);
456             mEditor = createViews(this, false /* showWhenLocked */);
457         }
458     }
459 
460     public static class ShowWhenLockedImeActivity extends Activity {
461 
462         @Override
onCreate(Bundle icicle)463         protected void onCreate(Bundle icicle) {
464             super.onCreate(icicle);
465             createViews(this, true /* showWhenLocked */);
466         }
467     }
468 
createViews( Activity activity, boolean showWhenLocked )469     private static EditText createViews(
470             Activity activity, boolean showWhenLocked /* showWhenLocked */) {
471         EditText editor = new EditText(activity);
472         // Set private IME option for editorMatcher to identify which TextView received
473         // onStartInput event.
474         editor.setPrivateImeOptions(
475                 activity.getClass().getName()
476                         + "/" + Long.toString(SystemClock.elapsedRealtimeNanos()));
477         final LinearLayout layout = new LinearLayout(activity);
478         layout.setOrientation(LinearLayout.VERTICAL);
479         layout.addView(editor);
480         activity.setContentView(layout);
481 
482         if (showWhenLocked) {
483             // Set showWhenLocked as true & request focus for showing soft input.
484             activity.setShowWhenLocked(true);
485             activity.getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
486         }
487         editor.requestFocus();
488         return editor;
489     }
490 
491     /**
492      * Waits until the given activity has entered picture-in-picture mode (allowing for the
493      * subsequent animation to start).
494      */
waitForEnterPip(ComponentName activityName)495     private void waitForEnterPip(ComponentName activityName) {
496         mWmState.waitForValidState(new WaitForValidActivityState.Builder(activityName)
497                 .setWindowingMode(WINDOWING_MODE_PINNED)
498                 .setActivityType(ACTIVITY_TYPE_STANDARD)
499                 .build());
500     }
501 }
502