• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 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 com.android.server.wm;
18 
19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
21 import static com.android.server.wm.AppCompatLetterboxUtils.calculateLetterboxInnerBounds;
22 import static com.android.server.wm.AppCompatLetterboxUtils.calculateLetterboxOuterBounds;
23 import static com.android.server.wm.AppCompatLetterboxUtils.calculateLetterboxPosition;
24 
25 import static org.mockito.Mockito.mock;
26 
27 import android.graphics.Point;
28 import android.graphics.Rect;
29 import android.platform.test.annotations.Presubmit;
30 
31 import androidx.annotation.NonNull;
32 import androidx.test.filters.SmallTest;
33 
34 import org.junit.Assert;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 
38 import java.util.function.Consumer;
39 
40 /**
41  * Tests for the {@link AppCompatLetterboxUtils} class.
42  *
43  * Build/Install/Run:
44  * atest WmTests:AppCompatLetterboxUtilsTest
45  */
46 @SmallTest
47 @Presubmit
48 @RunWith(WindowTestRunner.class)
49 public class AppCompatLetterboxUtilsTest extends WindowTestsBase {
50 
51     @Test
allEmptyWhenIsAppNotLetterboxed()52     public void allEmptyWhenIsAppNotLetterboxed() {
53         runTestScenario((robot) -> {
54             robot.activity().createActivityWithComponent();
55             robot.setTopActivityLetterboxPolicyRunning(false);
56             robot.getLetterboxPosition();
57             robot.assertPosition(/* x */ 0, /* y */0);
58             robot.getInnerBounds();
59             robot.assertInnerBounds(/* left */ 0, /* top */ 0, /* right */ 0, /* bottom */ 0);
60             robot.getOuterBounds();
61             robot.assertOuterBounds(/* left */ 0, /* top */ 0, /* right */ 0, /* bottom */ 0);
62         });
63     }
64 
65     @Test
positionIsFromActivity()66     public void positionIsFromActivity() {
67         runTestScenario((robot) -> {
68             robot.activity().createActivityWithComponent();
69             robot.setTopActivityLetterboxPolicyRunning(true);
70             robot.activity().configureTopActivityBounds(
71                     new Rect(/* left */ 200, /* top */ 400, /* right */ 300, /* bottom */ 400));
72             robot.getLetterboxPosition();
73 
74             robot.assertPosition(/* x */ 200, /* y */ 400);
75         });
76     }
77 
78     @Test
outerBoundsWhenFixedRotationTransformDisplayBoundsIsAvailable()79     public void outerBoundsWhenFixedRotationTransformDisplayBoundsIsAvailable() {
80         runTestScenario((robot) -> {
81             robot.activity().createActivityWithComponent();
82             robot.setTopActivityLetterboxPolicyRunning(true);
83             robot.activity().setFixedRotationTransformDisplayBounds(
84                     new Rect(/* left */ 1, /* top */ 2, /* right */ 3, /* bottom */ 4));
85             robot.getOuterBounds();
86 
87             robot.assertOuterBounds(/* left */ 1, /* top */ 2, /* right */ 3, /* bottom */ 4);
88         });
89     }
90 
91     @Test
outerBoundsNoFixedRotationTransformDisplayBoundsInMultiWindow()92     public void outerBoundsNoFixedRotationTransformDisplayBoundsInMultiWindow() {
93         runTestScenario((robot) -> {
94             robot.activity().createActivityWithComponent();
95             robot.setTopActivityLetterboxPolicyRunning(true);
96             robot.activity().setFixedRotationTransformDisplayBounds(null);
97             robot.activity().setTopActivityInMultiWindowMode(true);
98             robot.getOuterBounds();
99 
100             robot.checkOuterBoundsAreTaskFragmentBounds();
101         });
102     }
103 
104     @Test
outerBoundsNoFixedRotationTransformDisplayBoundsNotInMultiWindow()105     public void outerBoundsNoFixedRotationTransformDisplayBoundsNotInMultiWindow() {
106         runTestScenario((robot) -> {
107             robot.activity().createActivityWithComponent();
108             robot.setTopActivityLetterboxPolicyRunning(true);
109             robot.activity().setFixedRotationTransformDisplayBounds(null);
110             robot.activity().setTopActivityInMultiWindowMode(false);
111             robot.getOuterBounds();
112 
113             robot.checkOuterBoundsAreRootTaskParentBounds();
114         });
115     }
116 
117     @Test
innerBoundsTransparencyPolicyIsRunning()118     public void innerBoundsTransparencyPolicyIsRunning() {
119         runTestScenario((robot) -> {
120             robot.activity().createActivityWithComponent();
121             robot.setTopActivityLetterboxPolicyRunning(true);
122             robot.setTopActivityTransparentPolicyRunning(true);
123 
124             robot.getInnerBounds();
125 
126             robot.checkInnerBoundsAreActivityBounds();
127         });
128     }
129 
130     @Test
innerBoundsTransparencyPolicyIsNotRunning()131     public void innerBoundsTransparencyPolicyIsNotRunning() {
132         runTestScenario((robot) -> {
133             robot.activity().createActivityWithComponent();
134             robot.setTopActivityLetterboxPolicyRunning(true);
135             robot.setTopActivityTransparentPolicyRunning(false);
136             robot.setWindowFrame(
137                     new Rect(/* left */ 100, /* top */ 200, /* right */ 300, /* bottom */ 400));
138 
139             robot.getInnerBounds();
140 
141             robot.assertInnerBounds(/* left */ 100, /* top */ 200, /* right */ 300, /* bottom */
142                     400);
143         });
144     }
145 
146     /**
147      * Runs a test scenario providing a Robot.
148      */
runTestScenario(@onNull Consumer<LetterboxUtilsRobotTest> consumer)149     void runTestScenario(@NonNull Consumer<LetterboxUtilsRobotTest> consumer) {
150         final LetterboxUtilsRobotTest robot = new LetterboxUtilsRobotTest(mWm, mAtm, mSupervisor);
151         consumer.accept(robot);
152     }
153 
154     private static class LetterboxUtilsRobotTest extends AppCompatRobotBase {
155 
156         private final Point mPosition = new Point();
157         private final Rect mInnerBound = new Rect();
158         private final Rect mOuterBound = new Rect();
159 
160         @NonNull
161         private final WindowState mWindowState;
162 
LetterboxUtilsRobotTest(@onNull WindowManagerService wm, @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor)163         LetterboxUtilsRobotTest(@NonNull WindowManagerService wm,
164                 @NonNull ActivityTaskManagerService atm,
165                 @NonNull ActivityTaskSupervisor supervisor) {
166             super(wm, atm, supervisor);
167             mWindowState = mock(WindowState.class);
168         }
169 
170         @Override
onPostActivityCreation(@onNull ActivityRecord activity)171         void onPostActivityCreation(@NonNull ActivityRecord activity) {
172             super.onPostActivityCreation(activity);
173             spyOn(activity.mAppCompatController.getLetterboxPolicy());
174             spyOn(activity.mAppCompatController.getTransparentPolicy());
175         }
176 
setTopActivityLetterboxPolicyRunning(boolean running)177         void setTopActivityLetterboxPolicyRunning(boolean running) {
178             doReturn(running).when(activity().top().mAppCompatController
179                     .getLetterboxPolicy()).isRunning();
180         }
181 
setTopActivityTransparentPolicyRunning(boolean running)182         void setTopActivityTransparentPolicyRunning(boolean running) {
183             doReturn(running).when(activity().top().mAppCompatController
184                     .getTransparentPolicy()).isRunning();
185         }
186 
setWindowFrame(@onNull Rect frame)187         void setWindowFrame(@NonNull Rect frame) {
188             doReturn(frame).when(mWindowState).getFrame();
189         }
190 
getLetterboxPosition()191         void getLetterboxPosition() {
192             calculateLetterboxPosition(activity().top(), mPosition);
193         }
194 
getInnerBounds()195         void getInnerBounds() {
196             calculateLetterboxInnerBounds(activity().top(), mWindowState, mInnerBound);
197         }
198 
getOuterBounds()199         void getOuterBounds() {
200             calculateLetterboxOuterBounds(activity().top(), mOuterBound);
201         }
202 
assertPosition(int expectedX, int expectedY)203         void assertPosition(int expectedX, int expectedY) {
204             Assert.assertEquals(expectedX, mPosition.x);
205             Assert.assertEquals(expectedY, mPosition.y);
206         }
207 
assertInnerBounds(int expectedLeft, int expectedTop, int expectedRight, int expectedBottom)208         void assertInnerBounds(int expectedLeft, int expectedTop, int expectedRight,
209                 int expectedBottom) {
210             Assert.assertEquals(expectedLeft, mInnerBound.left);
211             Assert.assertEquals(expectedTop, mInnerBound.top);
212             Assert.assertEquals(expectedRight, mInnerBound.right);
213             Assert.assertEquals(expectedBottom, mInnerBound.bottom);
214         }
215 
assertOuterBounds(int expectedLeft, int expectedTop, int expectedRight, int expectedBottom)216         void assertOuterBounds(int expectedLeft, int expectedTop, int expectedRight,
217                 int expectedBottom) {
218             Assert.assertEquals(expectedLeft, mOuterBound.left);
219             Assert.assertEquals(expectedTop, mOuterBound.top);
220             Assert.assertEquals(expectedRight, mOuterBound.right);
221             Assert.assertEquals(expectedBottom, mOuterBound.bottom);
222         }
223 
checkOuterBoundsAreRootTaskParentBounds()224         void checkOuterBoundsAreRootTaskParentBounds() {
225             Assert.assertEquals(mOuterBound,
226                     activity().top().getRootTask().getParent().getBounds());
227         }
228 
checkOuterBoundsAreTaskFragmentBounds()229         void checkOuterBoundsAreTaskFragmentBounds() {
230             Assert.assertEquals(mOuterBound,
231                     activity().top().getTaskFragment().getBounds());
232         }
233 
checkInnerBoundsAreActivityBounds()234         void checkInnerBoundsAreActivityBounds() {
235             Assert.assertEquals(mInnerBound, activity().top().getBounds());
236         }
237 
238     }
239 }
240