1 /*
2  * Copyright (C) 2020 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 com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.assertTrue;
22 
23 import android.content.Intent;
24 import android.platform.test.annotations.Presubmit;
25 import android.server.wm.app.Components;
26 import android.view.Display;
27 
28 import org.junit.Test;
29 
30 import java.util.List;
31 
32 /**
33  * Build/Install/Run:
34  *     atest CtsWindowManagerDeviceTestCases:PresentationTest
35  */
36 @Presubmit
37 public class PresentationTest extends MultiDisplayTestBase {
38 
39     // WindowManager.LayoutParams.TYPE_PRESENTATION
40     private static final int TYPE_PRESENTATION = 2037;
41 
42     @Test
testPresentationFollowsDisplayFlag()43     public void testPresentationFollowsDisplayFlag() {
44         for (Display display : mDm.getDisplays()) {
45             launchPresentationActivity(display.getDisplayId());
46             if ((display.getFlags() & Display.FLAG_PRESENTATION) != Display.FLAG_PRESENTATION) {
47                 assertNoPresentationDisplayed();
48             } else {
49                 assertPresentationOnDisplayAndMatchesDisplayMetrics(display.getDisplayId());
50             }
51         }
52     }
53 
54     @Test
testPresentationAllowedOnPresentationDisplay()55     public void testPresentationAllowedOnPresentationDisplay() {
56         WindowManagerState.DisplayContent display =
57                 createManagedVirtualDisplaySession()
58                         .setPresentationDisplay(true)
59                         .setPublicDisplay(true)
60                         .createDisplay();
61 
62         assertThat(display.getFlags() & Display.FLAG_PRESENTATION)
63                 .isEqualTo(Display.FLAG_PRESENTATION);
64 
65         launchPresentationActivity(display.mId);
66         assertPresentationOnDisplayAndMatchesDisplayMetrics(display.mId);
67     }
68 
69     @Test
testPresentationNotDismissAfterResizeDisplay()70     public void testPresentationNotDismissAfterResizeDisplay() {
71         final VirtualDisplaySession virtualDisplaySession = createManagedVirtualDisplaySession();
72         WindowManagerState.DisplayContent display = virtualDisplaySession
73                         .setPresentationDisplay(true)
74                         .setPublicDisplay(true)
75                         .setResizeDisplay(false) // resize only through resizeDisplay call
76                         .createDisplay();
77 
78         assertThat(display.getFlags() & Display.FLAG_PRESENTATION)
79                 .isEqualTo(Display.FLAG_PRESENTATION);
80 
81         launchPresentationActivity(display.mId);
82         assertPresentationOnDisplayAndMatchesDisplayMetrics(display.mId);
83 
84         virtualDisplaySession.resizeDisplay();
85 
86         assertTrue("Presentation must not dismiss on external public display even if"
87                 + "display resize", mWmState.waitForWithAmState(
88                 state -> isPresentationOnDisplay(state, display.mId),
89                 "Presentation window still shows"));
90     }
91 
92     @Test
testPresentationBlockedOnNonPresentationDisplay()93     public void testPresentationBlockedOnNonPresentationDisplay() {
94         WindowManagerState.DisplayContent display =
95                 createManagedVirtualDisplaySession()
96                         .setPresentationDisplay(false)
97                         .createDisplay();
98 
99         assertThat(display.getFlags() & Display.FLAG_PRESENTATION).isEqualTo(0);
100         launchPresentationActivity(display.mId);
101         assertNoPresentationDisplayed();
102     }
103 
isPresentationOnDisplay(WindowManagerState windowManagerState, int displayId)104     private boolean isPresentationOnDisplay(WindowManagerState windowManagerState, int displayId) {
105         final List<WindowManagerState.WindowState> states =
106                 windowManagerState.getMatchingWindowType(TYPE_PRESENTATION);
107         for (WindowManagerState.WindowState ws : states) {
108             if (ws.getDisplayId() == displayId) return true;
109         }
110         return false;
111     }
112 
assertNoPresentationDisplayed()113     private void assertNoPresentationDisplayed() {
114         final List<WindowManagerState.WindowState> presentationWindows =
115                 mWmState.getWindowsByPackageName(
116                         Components.PRESENTATION_ACTIVITY.getPackageName(), TYPE_PRESENTATION);
117         assertThat(presentationWindows).isEmpty();
118     }
119 
assertPresentationOnDisplayAndMatchesDisplayMetrics(int displayId)120     private void assertPresentationOnDisplayAndMatchesDisplayMetrics(int displayId) {
121         final List<WindowManagerState.WindowState> presentationWindows =
122                 mWmState.getWindowsByPackageName(
123                         Components.PRESENTATION_ACTIVITY.getPackageName(), TYPE_PRESENTATION);
124         assertThat(presentationWindows).hasSize(1);
125         WindowManagerState.WindowState presentationWindowState = presentationWindows.get(0);
126         assertThat(presentationWindowState.getDisplayId()).isEqualTo(displayId);
127 
128         WindowManagerState.DisplayContent display = mWmState.getDisplay(displayId);
129         assertThat(display.getDisplayRect()).isEqualTo(
130                 presentationWindowState.mFullConfiguration.windowConfiguration.getBounds());
131     }
132 
launchPresentationActivity(int displayId)133     private void launchPresentationActivity(int displayId) {
134         Intent intent = new Intent();
135         intent.setComponent(Components.PRESENTATION_ACTIVITY);
136         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
137         intent.putExtra(Components.PresentationActivity.KEY_DISPLAY_ID, displayId);
138         mContext.startActivity(intent);
139         waitAndAssertTopResumedActivity(
140                 Components.PRESENTATION_ACTIVITY,
141                 Display.DEFAULT_DISPLAY,
142                 "Launched activity must be on top");
143     }
144 }
145