• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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_ASSISTANT;
20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
21 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
22 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
23 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
24 import static android.server.wm.CliIntentExtra.extraString;
25 import static android.server.wm.ComponentNameUtils.getActivityName;
26 import static android.server.wm.UiDeviceUtils.pressHomeButton;
27 import static android.server.wm.WindowManagerState.STATE_RESUMED;
28 import static android.server.wm.app.Components.ANIMATION_TEST_ACTIVITY;
29 import static android.server.wm.app.Components.ASSISTANT_ACTIVITY;
30 import static android.server.wm.app.Components.ASSISTANT_VOICE_INTERACTION_SERVICE;
31 import static android.server.wm.app.Components.AssistantActivity.EXTRA_ASSISTANT_DISPLAY_ID;
32 import static android.server.wm.app.Components.AssistantActivity.EXTRA_ASSISTANT_ENTER_PIP;
33 import static android.server.wm.app.Components.AssistantActivity.EXTRA_ASSISTANT_FINISH_SELF;
34 import static android.server.wm.app.Components.AssistantActivity.EXTRA_ASSISTANT_LAUNCH_NEW_TASK;
35 import static android.server.wm.app.Components.DOCKED_ACTIVITY;
36 import static android.server.wm.app.Components.LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION;
37 import static android.server.wm.app.Components.LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK;
38 import static android.server.wm.app.Components.LaunchAssistantActivityIntoAssistantStack.EXTRA_ASSISTANT_IS_TRANSLUCENT;
39 import static android.server.wm.app.Components.PIP_ACTIVITY;
40 import static android.server.wm.app.Components.PipActivity.EXTRA_ENTER_PIP;
41 import static android.server.wm.app.Components.TEST_ACTIVITY;
42 import static android.server.wm.app.Components.TRANSLUCENT_ASSISTANT_ACTIVITY;
43 import static android.server.wm.app.Components.TestActivity.TEST_ACTIVITY_ACTION_FINISH_SELF;
44 import static android.view.Display.DEFAULT_DISPLAY;
45 
46 import static org.hamcrest.Matchers.hasSize;
47 import static org.junit.Assert.assertEquals;
48 import static org.junit.Assert.assertThat;
49 import static org.junit.Assert.assertTrue;
50 import static org.junit.Assume.assumeTrue;
51 
52 import android.content.ComponentName;
53 import android.platform.test.annotations.Presubmit;
54 import android.provider.Settings;
55 import android.server.wm.settings.SettingsSession;
56 
57 import org.junit.Ignore;
58 import org.junit.Test;
59 
60 /**
61  * Build/Install/Run:
62  *     atest CtsWindowManagerDeviceTestCases:AssistantStackTests
63  */
64 @Presubmit
65 public class AssistantStackTests extends ActivityManagerTestBase {
66 
67     private int mAssistantDisplayId = DEFAULT_DISPLAY;
68 
setUp()69     public void setUp() throws Exception {
70         super.setUp();
71         try (final AssistantSession assistantSession = new AssistantSession()) {
72             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
73             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK);
74             waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
75             WindowManagerState.Task assistantStack =
76                     mWmState.getRootTaskByActivityType(ACTIVITY_TYPE_ASSISTANT);
77             mAssistantDisplayId = assistantStack.mDisplayId;
78         }
79     }
80 
81     @Test
testLaunchingAssistantActivityIntoAssistantStack()82     public void testLaunchingAssistantActivityIntoAssistantStack() throws Exception {
83         // Enable the assistant and launch an assistant activity
84         try (final AssistantSession assistantSession = new AssistantSession()) {
85             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
86 
87             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
88             waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
89 
90             // Ensure that the activity launched in the fullscreen assistant stack
91             assertAssistantStackExists();
92             // In a multi-window environment the assistant might not be fullscreen
93             assumeTrue(getDefaultDisplayWindowingMode() == WINDOWING_MODE_FULLSCREEN);
94             assertTrue("Expected assistant stack to be fullscreen",
95                     mWmState.getRootTaskByActivityType(
96                             ACTIVITY_TYPE_ASSISTANT).isFullscreen());
97         }
98     }
99 
100     @Test
testAssistantStackZOrder()101     public void testAssistantStackZOrder() throws Exception {
102         assumeTrue(assistantRunsOnPrimaryDisplay());
103         assumeTrue(supportsPip());
104         assumeTrue(supportsSplitScreenMultiWindow());
105 
106         // Launch a pinned stack task
107         launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"));
108         waitForValidStateWithActivityTypeAndWindowingMode(
109                 PIP_ACTIVITY, ACTIVITY_TYPE_STANDARD, WINDOWING_MODE_PINNED);
110         mWmState.assertContainsStack("Must contain pinned stack.",
111                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
112 
113         // Dock a task
114         launchActivitiesInSplitScreen(
115                 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY),
116                 getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY));
117 
118         // Enable the assistant and launch an assistant activity, ensure it is on top
119         try (final AssistantSession assistantSession = new AssistantSession()) {
120             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
121 
122             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION);
123             waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
124             assertAssistantStackExists();
125 
126             mWmState.assertFrontStack("Pinned stack should be on top.",
127                     WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
128             mWmState.assertFocusedRootTask("Assistant stack should be focused.",
129                     WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
130         }
131     }
132 
133     @Test
testAssistantStackLaunchNewTask()134     public void testAssistantStackLaunchNewTask() throws Exception {
135         assertAssistantStackCanLaunchAndReturnFromNewTask();
136     }
137 
138     @Test
139     @Ignore("b/77272253#comment10")
testAssistantStackLaunchNewTaskWithDockedStack()140     public void testAssistantStackLaunchNewTaskWithDockedStack() throws Exception {
141         assumeTrue(assistantRunsOnPrimaryDisplay());
142         assumeTrue(supportsSplitScreenMultiWindow());
143 
144         // Dock a task
145         launchActivitiesInSplitScreen(
146                 getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY),
147                 getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY));
148 
149         //assertAssistantStackCanLaunchAndReturnFromNewTask(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
150     }
151 
assertAssistantStackCanLaunchAndReturnFromNewTask()152     private void assertAssistantStackCanLaunchAndReturnFromNewTask()
153             throws Exception {
154         // Enable the assistant and launch an assistant activity which will launch a new task
155         try (final AssistantSession assistantSession = new AssistantSession()) {
156             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
157 
158             launchActivityOnDisplayNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK, mAssistantDisplayId,
159                     extraString(EXTRA_ASSISTANT_LAUNCH_NEW_TASK, getActivityName(TEST_ACTIVITY)),
160                     extraString(EXTRA_ASSISTANT_DISPLAY_ID, Integer.toString(mAssistantDisplayId)));
161             // Ensure that the fullscreen stack is on top and the test activity is now visible
162             waitForValidStateWithActivityType(TEST_ACTIVITY, ACTIVITY_TYPE_STANDARD);
163         }
164 
165         if (isAssistantOnTopOfDream()) {
166             // If the assistant is configured to be always-on-top, then the new task should have
167             // been started behind it and the assistant stack should still be on top.
168             mWmState.assertFocusedActivity(
169                     "AssistantActivity should be focused", ASSISTANT_ACTIVITY);
170             mWmState.assertFrontStackActivityType(
171                     "Assistant stack should be on top.", ACTIVITY_TYPE_ASSISTANT);
172             mWmState.assertFocusedRootTask("Assistant stack should be focused.",
173                     WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
174         } else {
175             final int testActivityWindowingMode =
176                     mWmState.getTaskDisplayArea(TEST_ACTIVITY).getWindowingMode();
177             mWmState.assertFocusedActivity("TestActivity should be resumed", TEST_ACTIVITY);
178             mWmState.assertFrontStack("TestActivity stack should be on top.",
179                     testActivityWindowingMode, ACTIVITY_TYPE_STANDARD);
180             mWmState.assertFocusedRootTask("TestActivity stack should be focused.",
181                     testActivityWindowingMode, ACTIVITY_TYPE_STANDARD);
182         }
183 
184         // Now, tell it to finish itself and ensure that the assistant stack is brought back forward
185         mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF);
186         mWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
187         mWmState.assertFrontStackActivityType(
188                 "Assistant stack should be on top.", ACTIVITY_TYPE_ASSISTANT);
189         mWmState.assertFocusedRootTask("Assistant stack should be focused.",
190                 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
191     }
192 
193     @Test
testAssistantStackFinishToPreviousApp()194     public void testAssistantStackFinishToPreviousApp() throws Exception {
195         // If the Assistant is configured to be always-on-top, then the assistant activity
196         // started in setUp() will not allow any other activities to start. Therefore we should
197         // remove it before launching a fullscreen activity.
198         if (isAssistantOnTopOfDream()) {
199             removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
200         }
201 
202         // Launch an assistant activity on top of an existing activity, and ensure that the activity
203         // is still visible and on top after the assistant activity finishes
204         launchActivityOnDisplay(TEST_ACTIVITY, mAssistantDisplayId);
205         try (final AssistantSession assistantSession = new AssistantSession()) {
206             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
207 
208             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
209                     extraString(EXTRA_ASSISTANT_FINISH_SELF, "true"));
210             mWmState.waitFor((amState) -> !amState.containsActivity(ASSISTANT_ACTIVITY),
211                     getActivityName(ASSISTANT_ACTIVITY) + " finished");
212         }
213         waitForValidStateWithActivityType(TEST_ACTIVITY, ACTIVITY_TYPE_STANDARD);
214         waitAndAssertTopResumedActivity(TEST_ACTIVITY, mAssistantDisplayId,
215                 "TestActivity should be resumed");
216         mWmState.assertFocusedActivity("TestActivity should be focused", TEST_ACTIVITY);
217 
218         final int testActivityWindowingMode =
219                 mWmState.getTaskDisplayArea(TEST_ACTIVITY).getWindowingMode();
220         mWmState.assertFrontStack("TestActivity stack should be on top.",
221                 testActivityWindowingMode, ACTIVITY_TYPE_STANDARD);
222         mWmState.assertFocusedRootTask("TestActivity stack should be focused.",
223                 testActivityWindowingMode, ACTIVITY_TYPE_STANDARD);
224     }
225 
226     @Test
testDisallowEnterPiPFromAssistantStack()227     public void testDisallowEnterPiPFromAssistantStack() throws Exception {
228         try (final AssistantSession assistantSession = new AssistantSession()) {
229             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
230 
231             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
232                     extraString(EXTRA_ASSISTANT_ENTER_PIP, "true"));
233         }
234         waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
235         mWmState.assertDoesNotContainStack("Must not contain pinned stack.",
236                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
237     }
238 
239     @Test
testTranslucentAssistantActivityStackVisibility()240     public void testTranslucentAssistantActivityStackVisibility() throws Exception {
241         try (final AssistantSession assistantSession = new AssistantSession()) {
242             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
243 
244             // Go home, launch the assistant and check to see that home is visible
245             removeRootTasksInWindowingModes(WINDOWING_MODE_FULLSCREEN);
246             pressHomeButton();
247             resumeAppSwitches();
248             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
249                     extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, "true"));
250             waitForValidStateWithActivityType(
251                     TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
252             assertAssistantStackExists();
253             mWmState.waitForHomeActivityVisible();
254             if (hasHomeScreen()) {
255                 mWmState.assertHomeActivityVisible(true);
256             }
257 
258             // Launch a fullscreen app and then launch the assistant and check to see that it is
259             // also visible
260             removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
261             launchActivityOnDisplay(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN, mAssistantDisplayId);
262             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
263                     extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, "true"));
264             waitForValidStateWithActivityType(
265                     TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
266             assertAssistantStackExists();
267             mWmState.assertVisibility(TEST_ACTIVITY, true);
268 
269             // Go home, launch assistant, launch app into fullscreen with activity present, and go
270             // back.Ensure home is visible.
271             removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
272             pressHomeButton();
273             resumeAppSwitches();
274             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
275                     extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, "true"),
276                     extraString(EXTRA_ASSISTANT_LAUNCH_NEW_TASK, getActivityName(TEST_ACTIVITY)));
277             waitForValidStateWithActivityType(TEST_ACTIVITY, ACTIVITY_TYPE_STANDARD);
278 
279             final ComponentName homeActivity = mWmState.getHomeActivityName();
280             int windowingMode = mWmState.getFocusedRootTaskWindowingMode();
281             // In a multi-window environment the home activity might not be fully covered
282             assumeTrue(windowingMode == WINDOWING_MODE_FULLSCREEN);
283 
284             // A WM Shell can implement a policy where there are more than one default
285             // Task Display Areas.
286             // If there are two task display areas, for example, left and right.
287             // When an activity is organized in left task display area it is still running in
288             // WINDOWING_MODE_FULLSCREEN. Having said that, home activity in default task display
289             // area is not fully covered. Thus, home activity is still resumed and visible.
290             // More than that, in the current AOSP 11 implementation, visibility and activity
291             // lifecycle work differently if activities are in the same task display area or in
292             // different task display areas.
293             // For example, if two task display areas have the exact same bounds,
294             // for the user, an activity running in the top task display area covers the activity
295             // running in the bottom task display area. However, because they are in separate
296             // display areas they will be both resumed.
297             // There can be cases where the bounds match but because tasks are in different
298             // task display area they are both resumed.
299             // So we check the activity bounds for two activities to confirm if task display
300             // areas are the same. If not the same, we will skip the visibility asserting test.
301             if (compareActivityBounds(homeActivity,
302                     ComponentName.unflattenFromString(mWmState.getFocusedActivity()))) {
303                 mWmState.waitAndAssertVisibilityGone(homeActivity);
304             }
305 
306             mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF);
307             mWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
308             assertAssistantStackExists();
309             mWmState.waitForHomeActivityVisible();
310             if (hasHomeScreen()) {
311                 mWmState.assertHomeActivityVisible(true);
312             }
313 
314             // Launch a fullscreen and docked app and then launch the assistant and check to see
315             // that it
316             // is also visible
317             if (supportsSplitScreenMultiWindow() &&  assistantRunsOnPrimaryDisplay()) {
318                 removeRootTasksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
319                 launchActivitiesInSplitScreen(
320                         getLaunchActivityBuilder().setTargetActivity(DOCKED_ACTIVITY),
321                         getLaunchActivityBuilder().setTargetActivity(TEST_ACTIVITY));
322                 launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
323                         extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, "true"));
324                 waitForValidStateWithActivityType(
325                         TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
326                 assertAssistantStackExists();
327                 mWmState.assertVisibility(DOCKED_ACTIVITY, true);
328                 mWmState.assertVisibility(TEST_ACTIVITY, true);
329             }
330         }
331     }
332 
333     @Test
testLaunchIntoSameTask()334     public void testLaunchIntoSameTask() throws Exception {
335         try (final AssistantSession assistantSession = new AssistantSession()) {
336             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
337 
338             // Launch the assistant
339             launchActivityOnDisplayNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION,
340                     mAssistantDisplayId);
341             waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
342             assertAssistantStackExists();
343             mWmState.assertVisibility(ASSISTANT_ACTIVITY, true);
344             mWmState.assertFocusedRootTask("Expected assistant stack focused",
345                     WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
346             final WindowManagerState amState = mWmState;
347             assertThat(amState.getRootTaskByActivityType(ACTIVITY_TYPE_ASSISTANT).getTasks(),
348                     hasSize(1));
349             final int taskId = mWmState.getTaskByActivity(ASSISTANT_ACTIVITY)
350                     .mTaskId;
351 
352             // Launch a new fullscreen activity
353             // Using Animation Test Activity because it is opaque on all devices.
354             launchActivityOnDisplay(ANIMATION_TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN, mAssistantDisplayId);
355             // If the activity is not launched in same TDA, ASSISTANT_ACTIVITY will be visible.
356             assumeTrue("Should launch in same TDA",
357                     mWmState.getTaskDisplayArea(ASSISTANT_ACTIVITY)
358                             == mWmState.getTaskDisplayArea(ANIMATION_TEST_ACTIVITY)
359             );
360             // Wait for animation finished.
361             mWmState.waitForActivityState(ANIMATION_TEST_ACTIVITY, STATE_RESUMED);
362 
363             if (isAssistantOnTopOfDream()) {
364                 mWmState.assertVisibility(ASSISTANT_ACTIVITY, true);
365             } else {
366                 mWmState.waitAndAssertVisibilityGone(ASSISTANT_ACTIVITY);
367             }
368 
369             // Launch the assistant again and ensure that it goes into the same task
370             launchActivityOnDisplayNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION,
371                     mAssistantDisplayId);
372             waitForValidStateWithActivityType(ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
373             assertAssistantStackExists();
374             mWmState.assertVisibility(ASSISTANT_ACTIVITY, true);
375             mWmState.assertFocusedRootTask("Expected assistant stack focused",
376                     WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
377             assertThat(amState.getRootTaskByActivityType(ACTIVITY_TYPE_ASSISTANT).getTasks(),
378                     hasSize(1));
379             assertEquals(taskId,
380                     mWmState.getTaskByActivity(ASSISTANT_ACTIVITY).mTaskId);
381 
382         }
383     }
384 
385     @Test
testPinnedStackWithAssistant()386     public void testPinnedStackWithAssistant() throws Exception {
387         assumeTrue(supportsPip());
388         assumeTrue(supportsSplitScreenMultiWindow());
389 
390         try (final AssistantSession assistantSession = new AssistantSession()) {
391             assistantSession.setVoiceInteractionService(ASSISTANT_VOICE_INTERACTION_SERVICE);
392 
393             // Launch a fullscreen activity and a PIP activity, then launch the assistant, and
394             // ensure that the test activity is still visible
395             launchActivity(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
396             launchActivity(PIP_ACTIVITY, extraString(EXTRA_ENTER_PIP, "true"));
397             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
398                     extraString(EXTRA_ASSISTANT_IS_TRANSLUCENT, String.valueOf(true)));
399             waitForValidStateWithActivityType(
400                     TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
401             assertAssistantStackExists();
402             mWmState.assertVisibility(TRANSLUCENT_ASSISTANT_ACTIVITY, true);
403             mWmState.assertVisibility(PIP_ACTIVITY, true);
404             mWmState.assertVisibility(TEST_ACTIVITY, true);
405 
406         }
407     }
408 
waitForValidStateWithActivityType(ComponentName activityName, int activityType)409     private void waitForValidStateWithActivityType(ComponentName activityName, int activityType)
410             throws Exception {
411         mWmState.waitForValidState(new WaitForValidActivityState.Builder(activityName)
412                 .setActivityType(activityType)
413                 .build());
414     }
415 
waitForValidStateWithActivityTypeAndWindowingMode(ComponentName activityName, int activityType, int windowingMode)416     private void waitForValidStateWithActivityTypeAndWindowingMode(ComponentName activityName,
417             int activityType, int windowingMode) throws Exception {
418         mWmState.waitForValidState(new WaitForValidActivityState.Builder(activityName)
419                 .setActivityType(activityType)
420                 .setWindowingMode(windowingMode)
421                 .build());
422     }
423 
424     /**
425      * Asserts that the assistant stack exists.
426      */
assertAssistantStackExists()427     private void assertAssistantStackExists() throws Exception {
428         mWmState.assertContainsStack("Must contain assistant stack.",
429                 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
430     }
431 
432     // Any 2D Activity in VR mode is run on a special VR virtual display, so check if the Assistant
433     // is going to run on the same display as other tasks.
assistantRunsOnPrimaryDisplay()434     protected boolean assistantRunsOnPrimaryDisplay() {
435         return mAssistantDisplayId == DEFAULT_DISPLAY;
436     }
437 
438     /**
439      * @return Windowing Mode from the default display
440      */
getDefaultDisplayWindowingMode()441     private int getDefaultDisplayWindowingMode() {
442         mWmState.computeState();
443         return mWmState.getDisplay(DEFAULT_DISPLAY).getWindowingMode();
444     }
445 
446     /** Helper class to save, set, and restore
447      * {@link Settings.Secure#VOICE_INTERACTION_SERVICE} system preference.
448      */
449     private static class AssistantSession extends SettingsSession<String> {
AssistantSession()450         AssistantSession() {
451             super(Settings.Secure.getUriFor(Settings.Secure.VOICE_INTERACTION_SERVICE),
452                     Settings.Secure::getString, Settings.Secure::putString);
453         }
454 
setVoiceInteractionService(ComponentName assistantName)455         void setVoiceInteractionService(ComponentName assistantName) throws Exception {
456             super.set(getActivityName(assistantName));
457         }
458     }
459 
460     /**
461      * Compare if bounds were the same between activities
462      */
compareActivityBounds(ComponentName activityName1, ComponentName activityName2)463     private boolean compareActivityBounds(ComponentName activityName1,
464             ComponentName activityName2) {
465         if (mWmState.getTaskByActivity(activityName1).getBounds()
466                 .equals(mWmState.getTaskByActivity(activityName2).getBounds())) {
467             return true;
468         }
469         return false;
470     }
471 }
472