AppWindowContainerControllerTests.java revision 11cc516a925ac7fc814dbb0a79a7f0abfbfe1ce1
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
17package com.android.server.wm;
18
19import org.junit.Test;
20
21import android.platform.test.annotations.Presubmit;
22import android.support.test.InstrumentationRegistry;
23import android.support.test.filters.SmallTest;
24import android.support.test.runner.AndroidJUnit4;
25
26import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
27import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
28import static android.content.res.Configuration.EMPTY;
29import static org.junit.Assert.assertEquals;
30import static org.junit.Assert.assertNotNull;
31import static org.junit.Assert.assertNull;
32import static org.junit.Assert.fail;
33
34/**
35 * Test class for {@link AppWindowContainerController}.
36 *
37 * Build/Install/Run:
38 *  bit FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests
39 */
40@SmallTest
41@Presubmit
42@org.junit.runner.RunWith(AndroidJUnit4.class)
43public class AppWindowContainerControllerTests extends WindowTestsBase {
44
45    @Test
46    public void testRemoveContainer() throws Exception {
47        final WindowTestUtils.TestAppWindowContainerController controller =
48                createAppWindowController();
49
50        // Assert token was added to display.
51        assertNotNull(mDisplayContent.getWindowToken(controller.mToken.asBinder()));
52        // Assert that the container was created and linked.
53        assertNotNull(controller.mContainer);
54
55        controller.removeContainer(mDisplayContent.getDisplayId());
56
57        // Assert token was remove from display.
58        assertNull(mDisplayContent.getWindowToken(controller.mToken.asBinder()));
59        // Assert that the container was removed.
60        assertNull(controller.mContainer);
61    }
62
63    @Test
64    public void testSetOrientation() throws Exception {
65        final WindowTestUtils.TestAppWindowContainerController controller =
66                createAppWindowController();
67
68        // Assert orientation is unspecified to start.
69        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, controller.getOrientation());
70
71        controller.setOrientation(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getDisplayId(),
72                EMPTY /* displayConfig */, false /* freezeScreenIfNeeded */);
73        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, controller.getOrientation());
74
75        controller.removeContainer(mDisplayContent.getDisplayId());
76        // Assert orientation is unspecified to after container is removed.
77        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, controller.getOrientation());
78
79        // Reset display frozen state
80        sWm.mDisplayFrozen = false;
81    }
82
83    private void assertHasStartingWindow(AppWindowToken atoken) {
84        assertNotNull(atoken.startingSurface);
85        assertNotNull(atoken.startingData);
86        assertNotNull(atoken.startingWindow);
87    }
88
89    private void assertNoStartingWindow(AppWindowToken atoken) {
90        assertNull(atoken.startingSurface);
91        assertNull(atoken.startingWindow);
92        assertNull(atoken.startingData);
93    }
94
95    @Test
96    public void testCreateRemoveStartingWindow() throws Exception {
97        final WindowTestUtils.TestAppWindowContainerController controller =
98                createAppWindowController();
99        controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
100                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
101        waitUntilHandlersIdle();
102        final AppWindowToken atoken = controller.getAppWindowToken(mDisplayContent);
103        assertHasStartingWindow(atoken);
104        controller.removeStartingWindow();
105        waitUntilHandlersIdle();
106        assertNoStartingWindow(atoken);
107    }
108
109    @Test
110    public void testTransferStartingWindow() throws Exception {
111        final WindowTestUtils.TestAppWindowContainerController controller1 =
112                createAppWindowController();
113        final WindowTestUtils.TestAppWindowContainerController controller2 =
114                createAppWindowController();
115        controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
116                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
117        waitUntilHandlersIdle();
118        controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
119                android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
120                true, true, false, true);
121        waitUntilHandlersIdle();
122        assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
123        assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
124    }
125
126    @Test
127    public void testTransferStartingWindowWhileCreating() throws Exception {
128        final WindowTestUtils.TestAppWindowContainerController controller1 =
129                createAppWindowController();
130        final WindowTestUtils.TestAppWindowContainerController controller2 =
131                createAppWindowController();
132        ((TestWindowManagerPolicy) sWm.mPolicy).setRunnableWhenAddingSplashScreen(() -> {
133
134            // Surprise, ...! Transfer window in the middle of the creation flow.
135            controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
136                    android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
137                    true, true, false, true);
138        });
139        controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
140                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
141        waitUntilHandlersIdle();
142        assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
143        assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
144    }
145
146    @Test
147    public void testReparent() throws Exception {
148        final StackWindowController stackController =
149            createStackControllerOnDisplay(mDisplayContent);
150        final WindowTestUtils.TestTaskWindowContainerController taskController1 =
151                new WindowTestUtils.TestTaskWindowContainerController(stackController);
152        final WindowTestUtils.TestAppWindowContainerController appWindowController1 =
153                createAppWindowController(taskController1);
154        final WindowTestUtils.TestTaskWindowContainerController taskController2 =
155                new WindowTestUtils.TestTaskWindowContainerController(stackController);
156        final WindowTestUtils.TestAppWindowContainerController appWindowController2 =
157                createAppWindowController(taskController2);
158        final WindowTestUtils.TestTaskWindowContainerController taskController3 =
159                new WindowTestUtils.TestTaskWindowContainerController(stackController);
160
161        try {
162            appWindowController1.reparent(taskController1, 0);
163            fail("Should not be able to reparent to the same parent");
164        } catch (IllegalArgumentException e) {
165            // Expected
166        }
167
168        try {
169            taskController3.setContainer(null);
170            appWindowController1.reparent(taskController3, 0);
171            fail("Should not be able to reparent to a task that doesn't have a container");
172        } catch (IllegalArgumentException e) {
173            // Expected
174        }
175
176        // Reparent the app window and ensure that it is moved
177        appWindowController1.reparent(taskController2, 0);
178        assertEquals(taskController2.mContainer, appWindowController1.mContainer.getParent());
179        assertEquals(0, ((WindowTestUtils.TestAppWindowToken) appWindowController1.mContainer)
180                .positionInParent());
181        assertEquals(1, ((WindowTestUtils.TestAppWindowToken) appWindowController2.mContainer)
182                .positionInParent());
183    }
184
185    private WindowTestUtils.TestAppWindowContainerController createAppWindowController() {
186        return createAppWindowController(
187                new WindowTestUtils.TestTaskWindowContainerController(this));
188    }
189
190    private WindowTestUtils.TestAppWindowContainerController createAppWindowController(
191            WindowTestUtils.TestTaskWindowContainerController taskController) {
192        return new WindowTestUtils.TestAppWindowContainerController(taskController);
193    }
194}
195