1 /*
2  * Copyright (C) 2022 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 android.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
20 import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
21 import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION;
22 import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
23 import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
24 import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
25 import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
26 import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
27 import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
28 import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
29 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
30 import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
31 import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
32 import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT;
33 import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
34 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
35 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
36 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
37 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
38 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
39 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
40 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
41 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
42 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
43 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
44 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
45 import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
46 import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
47 import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
48 import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
49 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
50 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
51 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
52 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
53 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
54 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
55 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
56 import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
57 import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
58 
59 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
60 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
61 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
62 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
63 import static com.android.server.wm.LetterboxUiController.MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP;
64 import static com.android.server.wm.LetterboxUiController.SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS;
65 
66 import static org.junit.Assert.assertEquals;
67 import static org.junit.Assert.assertFalse;
68 import static org.junit.Assert.assertNotEquals;
69 import static org.junit.Assert.assertNotNull;
70 import static org.junit.Assert.assertNull;
71 import static org.junit.Assert.assertTrue;
72 import static org.mockito.ArgumentMatchers.anyString;
73 import static org.mockito.Mockito.verify;
74 
75 import android.annotation.Nullable;
76 import android.compat.testing.PlatformCompatChangeRule;
77 import android.content.ComponentName;
78 import android.content.pm.PackageManager;
79 import android.content.pm.PackageManager.Property;
80 import android.content.res.Resources;
81 import android.graphics.Rect;
82 import android.platform.test.annotations.Presubmit;
83 import android.view.InsetsSource;
84 import android.view.InsetsState;
85 import android.view.RoundedCorner;
86 import android.view.RoundedCorners;
87 import android.view.WindowInsets;
88 import android.view.WindowManager;
89 
90 import androidx.test.filters.SmallTest;
91 
92 import com.android.internal.R;
93 
94 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
95 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
96 
97 import org.junit.Before;
98 import org.junit.Rule;
99 import org.junit.Test;
100 import org.junit.rules.TestRule;
101 import org.junit.runner.RunWith;
102 
103  /**
104  * Test class for {@link LetterboxUiControllerTest}.
105  *
106  * Build/Install/Run:
107  *  atest WmTests:LetterboxUiControllerTest
108  */
109 @SmallTest
110 @Presubmit
111 @RunWith(WindowTestRunner.class)
112 public class LetterboxUiControllerTest extends WindowTestsBase {
113     private static final int TASKBAR_COLLAPSED_HEIGHT = 10;
114     private static final int TASKBAR_EXPANDED_HEIGHT = 20;
115     private static final int SCREEN_WIDTH = 200;
116     private static final int SCREEN_HEIGHT = 100;
117     private static final Rect TASKBAR_COLLAPSED_BOUNDS = new Rect(0,
118             SCREEN_HEIGHT - TASKBAR_COLLAPSED_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT);
119     private static final Rect TASKBAR_EXPANDED_BOUNDS = new Rect(0,
120             SCREEN_HEIGHT - TASKBAR_EXPANDED_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT);
121 
122     @Rule
123     public TestRule compatChangeRule = new PlatformCompatChangeRule();
124 
125     private ActivityRecord mActivity;
126     private Task mTask;
127     private DisplayContent mDisplayContent;
128     private LetterboxUiController mController;
129     private LetterboxConfiguration mLetterboxConfiguration;
130     private final Rect mLetterboxedPortraitTaskBounds = new Rect();
131 
132     @Before
setUp()133     public void setUp() throws Exception {
134         mActivity = setUpActivityWithComponent();
135 
136         mLetterboxConfiguration = mWm.mLetterboxConfiguration;
137         spyOn(mLetterboxConfiguration);
138 
139         mController = new LetterboxUiController(mWm, mActivity);
140     }
141 
142     // shouldIgnoreRequestedOrientation
143 
144     @Test
145     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue()146     public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
147         prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
148 
149         assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
150     }
151 
152     @Test
153     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue()154     public void testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue() {
155         doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
156         doReturn(true).when(mLetterboxConfiguration)
157                 .isCameraCompatTreatmentEnabledAtBuildTime();
158 
159         // Recreate DisplayContent with DisplayRotationCompatPolicy
160         mActivity = setUpActivityWithComponent();
161         mController = new LetterboxUiController(mWm, mActivity);
162         prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
163         mController.setRelaunchingAfterRequestedOrientationChanged(false);
164 
165         spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
166         doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
167                 .isTreatmentEnabledForActivity(eq(mActivity));
168 
169         assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
170     }
171 
172     @Test
testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse()173     public void testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse() {
174         prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
175 
176         assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
177     }
178 
179     @Test
testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue()180     public void testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue()
181             throws Exception {
182         doReturn(true).when(mLetterboxConfiguration)
183                 .isPolicyForIgnoringRequestedOrientationEnabled();
184         mockThatProperty(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION, /* value */ true);
185         mController = new LetterboxUiController(mWm, mActivity);
186         prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
187 
188         assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
189     }
190 
191     @Test
192     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()193     public void testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()
194             throws Exception {
195         doReturn(true).when(mLetterboxConfiguration)
196                 .isPolicyForIgnoringRequestedOrientationEnabled();
197         mockThatProperty(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION, /* value */ false);
198 
199         mController = new LetterboxUiController(mWm, mActivity);
200         prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
201 
202         assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
203     }
204 
205     @Test
testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse()206     public void testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse() {
207         doReturn(true).when(mLetterboxConfiguration)
208                 .isPolicyForIgnoringRequestedOrientationEnabled();
209         doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
210         // Request 3 times to simulate orientation request loop
211         for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
212             assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
213                     /* expectedCount */ 0);
214         }
215     }
216 
217     @Test
218     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
testShouldIgnoreOrientationRequestLoop_propertyIsFalseAndOverride_returnsFalse()219     public void testShouldIgnoreOrientationRequestLoop_propertyIsFalseAndOverride_returnsFalse()
220             throws Exception {
221         doReturn(true).when(mLetterboxConfiguration)
222                 .isPolicyForIgnoringRequestedOrientationEnabled();
223         mockThatProperty(PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED,
224                 /* value */ false);
225         doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
226 
227         mController = new LetterboxUiController(mWm, mActivity);
228 
229         // Request 3 times to simulate orientation request loop
230         for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
231             assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
232                     /* expectedCount */ 0);
233         }
234     }
235 
236     @Test
237     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
testShouldIgnoreOrientationRequestLoop_isLetterboxed_returnsFalse()238     public void testShouldIgnoreOrientationRequestLoop_isLetterboxed_returnsFalse() {
239         doReturn(true).when(mLetterboxConfiguration)
240                 .isPolicyForIgnoringRequestedOrientationEnabled();
241         doReturn(true).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
242 
243         // Request 3 times to simulate orientation request loop
244         for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
245             assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
246                     /* expectedCount */ i);
247         }
248     }
249 
250     @Test
251     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
testShouldIgnoreOrientationRequestLoop_noLoop_returnsFalse()252     public void testShouldIgnoreOrientationRequestLoop_noLoop_returnsFalse() {
253         doReturn(true).when(mLetterboxConfiguration)
254                 .isPolicyForIgnoringRequestedOrientationEnabled();
255         doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
256 
257         // No orientation request loop
258         assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
259                 /* expectedCount */ 0);
260     }
261 
262     @Test
263     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
testShouldIgnoreOrientationRequestLoop_timeout_returnsFalse()264     public void testShouldIgnoreOrientationRequestLoop_timeout_returnsFalse()
265             throws InterruptedException {
266         doReturn(true).when(mLetterboxConfiguration)
267                 .isPolicyForIgnoringRequestedOrientationEnabled();
268         doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
269 
270         for (int i = MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i > 0; i--) {
271             assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
272                     /* expectedCount */ 0);
273             Thread.sleep(SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS);
274         }
275     }
276 
277     @Test
278     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
testShouldIgnoreOrientationRequestLoop_returnsTrue()279     public void testShouldIgnoreOrientationRequestLoop_returnsTrue() {
280         doReturn(true).when(mLetterboxConfiguration)
281                 .isPolicyForIgnoringRequestedOrientationEnabled();
282         doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
283 
284         for (int i = 0; i < MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
285             assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
286                     /* expectedCount */ i);
287         }
288         assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ true,
289                 /* expectedCount */ MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP);
290     }
291 
assertShouldIgnoreOrientationRequestLoop(boolean shouldIgnore, int expectedCount)292     private void assertShouldIgnoreOrientationRequestLoop(boolean shouldIgnore, int expectedCount) {
293         if (shouldIgnore) {
294             assertTrue(mController.shouldIgnoreOrientationRequestLoop());
295         } else {
296             assertFalse(mController.shouldIgnoreOrientationRequestLoop());
297         }
298         assertEquals(expectedCount, mController.getSetOrientationRequestCounter());
299     }
300 
301     @Test
302     @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse()303     public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
304         prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
305         doReturn(false).when(mLetterboxConfiguration)
306                 .isPolicyForIgnoringRequestedOrientationEnabled();
307 
308         assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
309     }
310 
311     // shouldRefreshActivityForCameraCompat
312 
313     @Test
testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse()314     public void testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse() {
315         doReturn(false).when(mLetterboxConfiguration)
316                 .isCameraCompatTreatmentEnabled();
317 
318         assertFalse(mController.shouldRefreshActivityForCameraCompat());
319     }
320 
321     @Test
322     @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse()323     public void testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse() {
324         doReturn(true).when(mLetterboxConfiguration)
325                 .isCameraCompatTreatmentEnabled();
326 
327         assertFalse(mController.shouldRefreshActivityForCameraCompat());
328     }
329 
330     @Test
331     @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse()332     public void testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
333             throws Exception {
334         doReturn(true).when(mLetterboxConfiguration)
335                 .isCameraCompatTreatmentEnabled();
336         mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
337 
338         mController = new LetterboxUiController(mWm, mActivity);
339 
340         assertFalse(mController.shouldRefreshActivityForCameraCompat());
341     }
342 
343     @Test
testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse()344     public void testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse()
345             throws Exception {
346         doReturn(true).when(mLetterboxConfiguration)
347                 .isCameraCompatTreatmentEnabled();
348         mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ false);
349 
350         mController = new LetterboxUiController(mWm, mActivity);
351 
352         assertFalse(mController.shouldRefreshActivityForCameraCompat());
353     }
354 
355     @Test
testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue()356     public void testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue()
357             throws Exception {
358         doReturn(true).when(mLetterboxConfiguration)
359                 .isCameraCompatTreatmentEnabled();
360         mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
361 
362         mController = new LetterboxUiController(mWm, mActivity);
363 
364         assertTrue(mController.shouldRefreshActivityForCameraCompat());
365     }
366 
367     // shouldRefreshActivityViaPauseForCameraCompat
368 
369     @Test
370     @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse()371     public void testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse() {
372         doReturn(false).when(mLetterboxConfiguration)
373                 .isCameraCompatTreatmentEnabled();
374 
375         assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
376     }
377 
378     @Test
379     @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue()380     public void testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue() {
381         doReturn(true).when(mLetterboxConfiguration)
382                 .isCameraCompatTreatmentEnabled();
383 
384         assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
385     }
386 
387     @Test
388     @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
testShouldRefreshActivityViaPauseForCameraCompat_propertyIsFalseAndOverride_returnFalse()389     public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsFalseAndOverride_returnFalse()
390             throws Exception {
391         doReturn(true).when(mLetterboxConfiguration)
392                 .isCameraCompatTreatmentEnabled();
393         mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ false);
394 
395         mController = new LetterboxUiController(mWm, mActivity);
396 
397         assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
398     }
399 
400     @Test
testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue()401     public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue()
402             throws Exception {
403         doReturn(true).when(mLetterboxConfiguration)
404                 .isCameraCompatTreatmentEnabled();
405         mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ true);
406 
407         mController = new LetterboxUiController(mWm, mActivity);
408 
409         assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
410     }
411 
412     // shouldForceRotateForCameraCompat
413 
414     @Test
testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse()415     public void testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse() {
416         doReturn(false).when(mLetterboxConfiguration)
417                 .isCameraCompatTreatmentEnabled();
418 
419         assertFalse(mController.shouldForceRotateForCameraCompat());
420     }
421 
422     @Test
423     @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse()424     public void testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse() {
425         doReturn(true).when(mLetterboxConfiguration)
426                 .isCameraCompatTreatmentEnabled();
427 
428         assertFalse(mController.shouldForceRotateForCameraCompat());
429     }
430 
431     @Test
432     @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse()433     public void testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
434             throws Exception {
435         doReturn(true).when(mLetterboxConfiguration)
436                 .isCameraCompatTreatmentEnabled();
437         mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
438 
439         mController = new LetterboxUiController(mWm, mActivity);
440 
441         assertFalse(mController.shouldForceRotateForCameraCompat());
442     }
443 
444     @Test
testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse()445     public void testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse()
446             throws Exception {
447         doReturn(true).when(mLetterboxConfiguration)
448                 .isCameraCompatTreatmentEnabled();
449         mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ false);
450 
451         mController = new LetterboxUiController(mWm, mActivity);
452 
453         assertFalse(mController.shouldForceRotateForCameraCompat());
454     }
455 
456     @Test
testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue()457     public void testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue()
458             throws Exception {
459         doReturn(true).when(mLetterboxConfiguration)
460                 .isCameraCompatTreatmentEnabled();
461         mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
462 
463         mController = new LetterboxUiController(mWm, mActivity);
464 
465         assertTrue(mController.shouldForceRotateForCameraCompat());
466     }
467 
468     @Test
testGetCropBoundsIfNeeded_handleCropForTransparentActivityBasedOnOpaqueBounds()469     public void testGetCropBoundsIfNeeded_handleCropForTransparentActivityBasedOnOpaqueBounds() {
470         final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
471                  WindowInsets.Type.navigationBars());
472         taskbar.setFlags(FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER);
473         final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(taskbar);
474         final Rect opaqueBounds = new Rect(0, 0, 500, 300);
475         doReturn(opaqueBounds).when(mActivity).getBounds();
476         // Activity is translucent
477         spyOn(mActivity.mLetterboxUiController);
478         doReturn(true).when(mActivity.mLetterboxUiController).hasInheritedLetterboxBehavior();
479 
480         // Makes requested sizes different
481         mainWindow.mRequestedWidth = opaqueBounds.width() - 1;
482         mainWindow.mRequestedHeight = opaqueBounds.height() - 1;
483         assertNull(mActivity.mLetterboxUiController.getCropBoundsIfNeeded(mainWindow));
484 
485         // Makes requested sizes equals
486         mainWindow.mRequestedWidth = opaqueBounds.width();
487         mainWindow.mRequestedHeight = opaqueBounds.height();
488         assertNotNull(mActivity.mLetterboxUiController.getCropBoundsIfNeeded(mainWindow));
489     }
490 
491     @Test
testGetCropBoundsIfNeeded_noCrop()492     public void testGetCropBoundsIfNeeded_noCrop() {
493         final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
494                 WindowInsets.Type.navigationBars());
495         final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(taskbar);
496 
497         // Do not apply crop if taskbar is collapsed
498         taskbar.setFrame(TASKBAR_COLLAPSED_BOUNDS);
499         assertNull(mController.getExpandedTaskbarOrNull(mainWindow));
500 
501         mLetterboxedPortraitTaskBounds.set(SCREEN_WIDTH / 4, SCREEN_HEIGHT / 4,
502                 SCREEN_WIDTH - SCREEN_WIDTH / 4, SCREEN_HEIGHT - SCREEN_HEIGHT / 4);
503 
504         final Rect noCrop = mController.getCropBoundsIfNeeded(mainWindow);
505         assertNotEquals(null, noCrop);
506         assertEquals(0, noCrop.left);
507         assertEquals(0, noCrop.top);
508         assertEquals(mLetterboxedPortraitTaskBounds.width(), noCrop.right);
509         assertEquals(mLetterboxedPortraitTaskBounds.height(), noCrop.bottom);
510     }
511 
512     @Test
testGetCropBoundsIfNeeded_appliesCrop()513     public void testGetCropBoundsIfNeeded_appliesCrop() {
514         final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
515                 WindowInsets.Type.navigationBars());
516         taskbar.setFlags(FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER);
517         final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(taskbar);
518 
519         // Apply crop if taskbar is expanded
520         taskbar.setFrame(TASKBAR_EXPANDED_BOUNDS);
521         assertNotNull(mController.getExpandedTaskbarOrNull(mainWindow));
522 
523         mLetterboxedPortraitTaskBounds.set(SCREEN_WIDTH / 4, 0, SCREEN_WIDTH - SCREEN_WIDTH / 4,
524                 SCREEN_HEIGHT);
525 
526         final Rect crop = mController.getCropBoundsIfNeeded(mainWindow);
527         assertNotEquals(null, crop);
528         assertEquals(0, crop.left);
529         assertEquals(0, crop.top);
530         assertEquals(mLetterboxedPortraitTaskBounds.width(), crop.right);
531         assertEquals(mLetterboxedPortraitTaskBounds.height() - TASKBAR_EXPANDED_HEIGHT,
532                 crop.bottom);
533     }
534 
535     @Test
testGetCropBoundsIfNeeded_appliesCropWithSizeCompatScaling()536     public void testGetCropBoundsIfNeeded_appliesCropWithSizeCompatScaling() {
537         final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
538                 WindowInsets.Type.navigationBars());
539         taskbar.setFlags(FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER);
540         final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(taskbar);
541         final float scaling = 2.0f;
542 
543         // Apply crop if taskbar is expanded
544         taskbar.setFrame(TASKBAR_EXPANDED_BOUNDS);
545         assertNotNull(mController.getExpandedTaskbarOrNull(mainWindow));
546         // With SizeCompat scaling
547         doReturn(true).when(mActivity).inSizeCompatMode();
548         mainWindow.mInvGlobalScale = scaling;
549 
550         mLetterboxedPortraitTaskBounds.set(SCREEN_WIDTH / 4, 0, SCREEN_WIDTH - SCREEN_WIDTH / 4,
551                 SCREEN_HEIGHT);
552 
553         final int appWidth = mLetterboxedPortraitTaskBounds.width();
554         final int appHeight = mLetterboxedPortraitTaskBounds.height();
555 
556         final Rect crop = mController.getCropBoundsIfNeeded(mainWindow);
557         assertNotEquals(null, crop);
558         assertEquals(0, crop.left);
559         assertEquals(0, crop.top);
560         assertEquals((int) (appWidth * scaling), crop.right);
561         assertEquals((int) ((appHeight - TASKBAR_EXPANDED_HEIGHT) * scaling), crop.bottom);
562     }
563 
564     @Test
testGetRoundedCornersRadius_withRoundedCornersFromInsets()565     public void testGetRoundedCornersRadius_withRoundedCornersFromInsets() {
566         final float invGlobalScale = 0.5f;
567         final int expectedRadius = 7;
568         final int configurationRadius = 15;
569 
570         final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(/*taskbar=*/ null);
571         mainWindow.mInvGlobalScale = invGlobalScale;
572         final InsetsState insets = mainWindow.getInsetsState();
573 
574         RoundedCorners roundedCorners = new RoundedCorners(
575                 /*topLeft=*/ null,
576                 /*topRight=*/ null,
577                 /*bottomRight=*/ new RoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT,
578                     configurationRadius, /*centerX=*/ 1, /*centerY=*/ 1),
579                 /*bottomLeft=*/ new RoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT,
580                     configurationRadius * 2 /*2 is to test selection of the min radius*/,
581                     /*centerX=*/ 1, /*centerY=*/ 1)
582         );
583         insets.setRoundedCorners(roundedCorners);
584         mLetterboxConfiguration.setLetterboxActivityCornersRadius(-1);
585 
586         assertEquals(expectedRadius, mController.getRoundedCornersRadius(mainWindow));
587     }
588 
589     @Test
testGetRoundedCornersRadius_withLetterboxActivityCornersRadius()590     public void testGetRoundedCornersRadius_withLetterboxActivityCornersRadius() {
591         final float invGlobalScale = 0.5f;
592         final int expectedRadius = 7;
593         final int configurationRadius = 15;
594 
595         final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(/*taskbar=*/ null);
596         mainWindow.mInvGlobalScale = invGlobalScale;
597         mLetterboxConfiguration.setLetterboxActivityCornersRadius(configurationRadius);
598 
599         doReturn(true).when(mActivity).isInLetterboxAnimation();
600         assertEquals(expectedRadius, mController.getRoundedCornersRadius(mainWindow));
601 
602         doReturn(false).when(mActivity).isInLetterboxAnimation();
603         assertEquals(expectedRadius, mController.getRoundedCornersRadius(mainWindow));
604 
605         doReturn(false).when(mainWindow).isOnScreen();
606         assertEquals(0, mController.getRoundedCornersRadius(mainWindow));
607 
608         doReturn(true).when(mActivity).isInLetterboxAnimation();
609         assertEquals(expectedRadius, mController.getRoundedCornersRadius(mainWindow));
610     }
611 
612     @Test
testGetRoundedCornersRadius_noScalingApplied()613     public void testGetRoundedCornersRadius_noScalingApplied() {
614         final int configurationRadius = 15;
615 
616         final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(/*taskbar=*/ null);
617         mLetterboxConfiguration.setLetterboxActivityCornersRadius(configurationRadius);
618 
619         mainWindow.mInvGlobalScale = -1f;
620         assertEquals(configurationRadius, mController.getRoundedCornersRadius(mainWindow));
621 
622         mainWindow.mInvGlobalScale = 0f;
623         assertEquals(configurationRadius, mController.getRoundedCornersRadius(mainWindow));
624 
625         mainWindow.mInvGlobalScale = 1f;
626         assertEquals(configurationRadius, mController.getRoundedCornersRadius(mainWindow));
627     }
628 
mockForGetCropBoundsAndRoundedCorners(@ullable InsetsSource taskbar)629     private WindowState mockForGetCropBoundsAndRoundedCorners(@Nullable InsetsSource taskbar) {
630         final WindowState mainWindow = mock(WindowState.class);
631         final InsetsState insets = new InsetsState();
632         final Resources resources = mWm.mContext.getResources();
633         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams();
634 
635         mainWindow.mInvGlobalScale = 1f;
636         spyOn(resources);
637         spyOn(mActivity);
638 
639         if (taskbar != null) {
640             taskbar.setVisible(true);
641             insets.addSource(taskbar);
642         }
643         doReturn(mLetterboxedPortraitTaskBounds).when(mActivity).getBounds();
644         doReturn(false).when(mActivity).isInLetterboxAnimation();
645         doReturn(true).when(mActivity).isVisible();
646         doReturn(true).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
647         doReturn(insets).when(mainWindow).getInsetsState();
648         doReturn(attrs).when(mainWindow).getAttrs();
649         doReturn(true).when(mainWindow).isDrawn();
650         doReturn(true).when(mainWindow).isOnScreen();
651         doReturn(false).when(mainWindow).isLetterboxedForDisplayCutout();
652         doReturn(true).when(mainWindow).areAppWindowBoundsLetterboxed();
653         doReturn(true).when(mLetterboxConfiguration).isLetterboxActivityCornersRounded();
654         doReturn(TASKBAR_EXPANDED_HEIGHT).when(resources).getDimensionPixelSize(
655                 R.dimen.taskbar_frame_height);
656 
657         // Need to reinitialise due to the change in resources getDimensionPixelSize output.
658         mController = new LetterboxUiController(mWm, mActivity);
659 
660         return mainWindow;
661     }
662 
663     // overrideOrientationIfNeeded
664 
665     @Test
testOverrideOrientationIfNeeded_mapInvokedOnRequest()666     public void testOverrideOrientationIfNeeded_mapInvokedOnRequest() throws Exception {
667         mController = new LetterboxUiController(mWm, mActivity);
668         spyOn(mWm);
669 
670         mController.overrideOrientationIfNeeded(SCREEN_ORIENTATION_PORTRAIT);
671 
672         verify(mWm).mapOrientationRequest(SCREEN_ORIENTATION_PORTRAIT);
673     }
674 
675     @Test
676     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsPortrait()677     public void testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsPortrait()
678             throws Exception {
679         assertEquals(mController.overrideOrientationIfNeeded(
680                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_PORTRAIT);
681     }
682 
683     @Test
684     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR})
testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsNosensor()685     public void testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsNosensor() {
686         assertEquals(mController.overrideOrientationIfNeeded(
687                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_NOSENSOR);
688     }
689 
690     @Test
691     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR})
testOverrideOrientationIfNeeded_nosensorOverride_orientationFixed_returnsUnchanged()692     public void testOverrideOrientationIfNeeded_nosensorOverride_orientationFixed_returnsUnchanged() {
693         assertEquals(mController.overrideOrientationIfNeeded(
694                 /* candidate */ SCREEN_ORIENTATION_PORTRAIT), SCREEN_ORIENTATION_PORTRAIT);
695     }
696 
697     @Test
698     @EnableCompatChanges({OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE})
testOverrideOrientationIfNeeded_reverseLandscapeOverride_orientationPortraitOrUndefined_returnsUnchanged()699     public void testOverrideOrientationIfNeeded_reverseLandscapeOverride_orientationPortraitOrUndefined_returnsUnchanged() {
700         assertEquals(mController.overrideOrientationIfNeeded(
701                 /* candidate */ SCREEN_ORIENTATION_PORTRAIT), SCREEN_ORIENTATION_PORTRAIT);
702         assertEquals(mController.overrideOrientationIfNeeded(
703                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_UNSPECIFIED);
704     }
705 
706     @Test
707     @EnableCompatChanges({OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE})
testOverrideOrientationIfNeeded_reverseLandscapeOverride_orientationLandscape_returnsReverseLandscape()708     public void testOverrideOrientationIfNeeded_reverseLandscapeOverride_orientationLandscape_returnsReverseLandscape() {
709         assertEquals(mController.overrideOrientationIfNeeded(
710                 /* candidate */ SCREEN_ORIENTATION_LANDSCAPE),
711                 SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
712     }
713 
714     @Test
715     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
testOverrideOrientationIfNeeded_portraitOverride_orientationFixed_returnsUnchanged()716     public void testOverrideOrientationIfNeeded_portraitOverride_orientationFixed_returnsUnchanged() {
717         assertEquals(mController.overrideOrientationIfNeeded(
718                 /* candidate */ SCREEN_ORIENTATION_NOSENSOR), SCREEN_ORIENTATION_NOSENSOR);
719     }
720 
721     @Test
722     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
testOverrideOrientationIfNeeded_portraitAndIgnoreFixedOverrides_returnsPortrait()723     public void testOverrideOrientationIfNeeded_portraitAndIgnoreFixedOverrides_returnsPortrait() {
724         assertEquals(mController.overrideOrientationIfNeeded(
725                 /* candidate */ SCREEN_ORIENTATION_NOSENSOR), SCREEN_ORIENTATION_PORTRAIT);
726     }
727 
728     @Test
729     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR, OVERRIDE_ANY_ORIENTATION})
testOverrideOrientationIfNeeded_noSensorAndIgnoreFixedOverrides_returnsNosensor()730     public void testOverrideOrientationIfNeeded_noSensorAndIgnoreFixedOverrides_returnsNosensor() {
731         assertEquals(mController.overrideOrientationIfNeeded(
732                 /* candidate */ SCREEN_ORIENTATION_PORTRAIT), SCREEN_ORIENTATION_NOSENSOR);
733     }
734 
735     @Test
736     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
testOverrideOrientationIfNeeded_propertyIsFalse_returnsUnchanged()737     public void testOverrideOrientationIfNeeded_propertyIsFalse_returnsUnchanged()
738             throws Exception {
739         mockThatProperty(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE, /* value */ false);
740 
741         mController = new LetterboxUiController(mWm, mActivity);
742 
743         assertEquals(mController.overrideOrientationIfNeeded(
744                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_UNSPECIFIED);
745     }
746 
747     @Test
748     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT,
749             OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
testOverrideOrientationIfNeeded_whenCameraNotActive_returnsUnchanged()750     public void testOverrideOrientationIfNeeded_whenCameraNotActive_returnsUnchanged() {
751         doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
752         doReturn(true).when(mLetterboxConfiguration)
753                 .isCameraCompatTreatmentEnabledAtBuildTime();
754 
755         // Recreate DisplayContent with DisplayRotationCompatPolicy
756         mActivity = setUpActivityWithComponent();
757         mController = new LetterboxUiController(mWm, mActivity);
758 
759         spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
760         doReturn(false).when(mDisplayContent.mDisplayRotationCompatPolicy)
761                 .isActivityEligibleForOrientationOverride(eq(mActivity));
762 
763         assertEquals(mController.overrideOrientationIfNeeded(
764                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_UNSPECIFIED);
765     }
766 
767     @Test
768     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT,
769             OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
testOverrideOrientationIfNeeded_whenCameraActive_returnsPortrait()770     public void testOverrideOrientationIfNeeded_whenCameraActive_returnsPortrait() {
771         doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
772         doReturn(true).when(mLetterboxConfiguration)
773                 .isCameraCompatTreatmentEnabledAtBuildTime();
774 
775         // Recreate DisplayContent with DisplayRotationCompatPolicy
776         mActivity = setUpActivityWithComponent();
777         mController = new LetterboxUiController(mWm, mActivity);
778 
779         spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
780         doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
781                 .isActivityEligibleForOrientationOverride(eq(mActivity));
782 
783         assertEquals(mController.overrideOrientationIfNeeded(
784                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_PORTRAIT);
785     }
786 
787     @Test
testOverrideOrientationIfNeeded_userFullscreenOverride_returnsUser()788     public void testOverrideOrientationIfNeeded_userFullscreenOverride_returnsUser() {
789         spyOn(mController);
790         doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
791 
792         assertEquals(mController.overrideOrientationIfNeeded(
793                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_USER);
794     }
795 
796     @Test
797     @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
testOverrideOrientationIfNeeded_userFullScreenOverrideOverSystem_returnsUser()798     public void testOverrideOrientationIfNeeded_userFullScreenOverrideOverSystem_returnsUser() {
799         spyOn(mController);
800         doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
801 
802         assertEquals(mController.overrideOrientationIfNeeded(
803                 /* candidate */ SCREEN_ORIENTATION_PORTRAIT), SCREEN_ORIENTATION_USER);
804     }
805 
806     @Test
testOverrideOrientationIfNeeded_userFullScreenOverrideDisabled_returnsUnchanged()807     public void testOverrideOrientationIfNeeded_userFullScreenOverrideDisabled_returnsUnchanged() {
808         spyOn(mController);
809         doReturn(false).when(mController).shouldApplyUserFullscreenOverride();
810 
811         assertEquals(mController.overrideOrientationIfNeeded(
812                 /* candidate */ SCREEN_ORIENTATION_PORTRAIT), SCREEN_ORIENTATION_PORTRAIT);
813     }
814 
815     @Test
testOverrideOrientationIfNeeded_userAspectRatioApplied_unspecifiedOverridden()816     public void testOverrideOrientationIfNeeded_userAspectRatioApplied_unspecifiedOverridden() {
817         spyOn(mController);
818         doReturn(true).when(mController).shouldApplyUserMinAspectRatioOverride();
819 
820         assertEquals(mController.overrideOrientationIfNeeded(
821                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_PORTRAIT);
822 
823         assertEquals(mController.overrideOrientationIfNeeded(
824                 /* candidate */ SCREEN_ORIENTATION_LOCKED), SCREEN_ORIENTATION_PORTRAIT);
825 
826         // unchanged if orientation is specified
827         assertEquals(mController.overrideOrientationIfNeeded(
828                 /* candidate */ SCREEN_ORIENTATION_LANDSCAPE), SCREEN_ORIENTATION_LANDSCAPE);
829     }
830 
831     @Test
testOverrideOrientationIfNeeded_userAspectRatioNotApplied_returnsUnchanged()832     public void testOverrideOrientationIfNeeded_userAspectRatioNotApplied_returnsUnchanged() {
833         spyOn(mController);
834         doReturn(false).when(mController).shouldApplyUserMinAspectRatioOverride();
835 
836         assertEquals(mController.overrideOrientationIfNeeded(
837                 /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED), SCREEN_ORIENTATION_UNSPECIFIED);
838     }
839 
840     // shouldApplyUser...Override
841     @Test
testShouldApplyUserFullscreenOverride_trueProperty_returnsFalse()842     public void testShouldApplyUserFullscreenOverride_trueProperty_returnsFalse() throws Exception {
843         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
844                 /* value */ true);
845 
846         mController = new LetterboxUiController(mWm, mActivity);
847         doReturn(false).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();
848 
849         assertFalse(mController.shouldApplyUserFullscreenOverride());
850     }
851 
852     @Test
testShouldApplyUserFullscreenOverride_falseFullscreenProperty_returnsFalse()853     public void testShouldApplyUserFullscreenOverride_falseFullscreenProperty_returnsFalse()
854             throws Exception {
855         prepareActivityThatShouldApplyUserFullscreenOverride();
856         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
857                 /* value */ false);
858 
859         mController = new LetterboxUiController(mWm, mActivity);
860 
861         assertFalse(mController.shouldApplyUserFullscreenOverride());
862     }
863 
864     @Test
testShouldApplyUserFullscreenOverride_falseSettingsProperty_returnsFalse()865     public void testShouldApplyUserFullscreenOverride_falseSettingsProperty_returnsFalse()
866             throws Exception {
867         prepareActivityThatShouldApplyUserFullscreenOverride();
868         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ false);
869 
870         mController = new LetterboxUiController(mWm, mActivity);
871 
872         assertFalse(mController.shouldApplyUserFullscreenOverride());
873     }
874 
875     @Test
testShouldApplyUserFullscreenOverride_disabledIgnoreOrientationRequest()876     public void testShouldApplyUserFullscreenOverride_disabledIgnoreOrientationRequest() {
877         prepareActivityThatShouldApplyUserFullscreenOverride();
878         mDisplayContent.setIgnoreOrientationRequest(false);
879 
880         assertFalse(mController.shouldApplyUserFullscreenOverride());
881     }
882 
883     @Test
testShouldApplyUserFullscreenOverride_returnsTrue()884     public void testShouldApplyUserFullscreenOverride_returnsTrue() {
885         prepareActivityThatShouldApplyUserFullscreenOverride();
886 
887         assertTrue(mController.shouldApplyUserFullscreenOverride());
888     }
889 
890     @Test
testShouldEnableUserAspectRatioSettings_falseProperty_returnsFalse()891     public void testShouldEnableUserAspectRatioSettings_falseProperty_returnsFalse()
892             throws Exception {
893         prepareActivityThatShouldApplyUserMinAspectRatioOverride();
894         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ false);
895 
896         mController = new LetterboxUiController(mWm, mActivity);
897 
898         assertFalse(mController.shouldEnableUserAspectRatioSettings());
899     }
900 
901     @Test
testShouldEnableUserAspectRatioSettings_trueProperty_returnsTrue()902     public void testShouldEnableUserAspectRatioSettings_trueProperty_returnsTrue()
903             throws Exception {
904         prepareActivityThatShouldApplyUserMinAspectRatioOverride();
905         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ true);
906 
907         mController = new LetterboxUiController(mWm, mActivity);
908 
909         assertTrue(mController.shouldEnableUserAspectRatioSettings());
910     }
911 
912     @Test
testShouldEnableUserAspectRatioSettings_noIgnoreOrientaion_returnsFalse()913     public void testShouldEnableUserAspectRatioSettings_noIgnoreOrientaion_returnsFalse()
914             throws Exception {
915         prepareActivityForShouldApplyUserMinAspectRatioOverride(/* orientationRequest */ false);
916         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ true);
917 
918         mController = new LetterboxUiController(mWm, mActivity);
919 
920         assertFalse(mController.shouldEnableUserAspectRatioSettings());
921     }
922 
923     @Test
testShouldApplyUserMinAspectRatioOverride_falseProperty_returnsFalse()924     public void testShouldApplyUserMinAspectRatioOverride_falseProperty_returnsFalse()
925             throws Exception {
926         prepareActivityThatShouldApplyUserMinAspectRatioOverride();
927         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ false);
928 
929         mController = new LetterboxUiController(mWm, mActivity);
930 
931         assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
932     }
933 
934     @Test
testShouldApplyUserMinAspectRatioOverride_trueProperty_returnsFalse()935     public void testShouldApplyUserMinAspectRatioOverride_trueProperty_returnsFalse()
936             throws Exception {
937         doReturn(false).when(mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
938         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ true);
939 
940         mController = new LetterboxUiController(mWm, mActivity);
941 
942         assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
943     }
944 
945     @Test
testShouldApplyUserMinAspectRatioOverride_disabledIgnoreOrientationRequest()946     public void testShouldApplyUserMinAspectRatioOverride_disabledIgnoreOrientationRequest() {
947         prepareActivityThatShouldApplyUserMinAspectRatioOverride();
948         mDisplayContent.setIgnoreOrientationRequest(false);
949 
950         assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
951     }
952 
953     @Test
testShouldApplyUserMinAspectRatioOverride_returnsTrue()954     public void testShouldApplyUserMinAspectRatioOverride_returnsTrue() {
955         prepareActivityThatShouldApplyUserMinAspectRatioOverride();
956 
957         assertTrue(mController.shouldApplyUserMinAspectRatioOverride());
958     }
959 
960     @Test
testShouldApplyUserMinAspectRatioOverride_noIgnoreOrientationreturnsFalse()961     public void testShouldApplyUserMinAspectRatioOverride_noIgnoreOrientationreturnsFalse() {
962         prepareActivityForShouldApplyUserMinAspectRatioOverride(/* orientationRequest */ false);
963 
964         assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
965     }
966 
prepareActivityForShouldApplyUserMinAspectRatioOverride( boolean orientationRequest)967     private void prepareActivityForShouldApplyUserMinAspectRatioOverride(
968             boolean orientationRequest) {
969         spyOn(mController);
970         doReturn(orientationRequest).when(
971                 mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
972         mDisplayContent.setIgnoreOrientationRequest(true);
973         doReturn(USER_MIN_ASPECT_RATIO_3_2).when(mController).getUserMinAspectRatioOverrideCode();
974     }
975 
prepareActivityThatShouldApplyUserMinAspectRatioOverride()976     private void prepareActivityThatShouldApplyUserMinAspectRatioOverride() {
977         prepareActivityForShouldApplyUserMinAspectRatioOverride(/* orientationRequest */ true);
978     }
979 
prepareActivityThatShouldApplyUserFullscreenOverride()980     private void prepareActivityThatShouldApplyUserFullscreenOverride() {
981         spyOn(mController);
982         doReturn(true).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();
983         mDisplayContent.setIgnoreOrientationRequest(true);
984         doReturn(USER_MIN_ASPECT_RATIO_FULLSCREEN).when(mController)
985                 .getUserMinAspectRatioOverrideCode();
986     }
987 
988     // shouldUseDisplayLandscapeNaturalOrientation
989 
990     @Test
991     @EnableCompatChanges({OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION})
testShouldUseDisplayLandscapeNaturalOrientation_override_returnsTrue()992     public void testShouldUseDisplayLandscapeNaturalOrientation_override_returnsTrue() {
993         prepareActivityThatShouldUseDisplayLandscapeNaturalOrientation();
994         assertTrue(mController.shouldUseDisplayLandscapeNaturalOrientation());
995     }
996 
997     @Test
998     @EnableCompatChanges({OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION})
testShouldUseDisplayLandscapeNaturalOrientation_overrideAndFalseProperty_returnsFalse()999     public void testShouldUseDisplayLandscapeNaturalOrientation_overrideAndFalseProperty_returnsFalse()
1000             throws Exception {
1001         mockThatProperty(PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE, /* value */ false);
1002 
1003         mController = new LetterboxUiController(mWm, mActivity);
1004 
1005         prepareActivityThatShouldUseDisplayLandscapeNaturalOrientation();
1006         assertFalse(mController.shouldUseDisplayLandscapeNaturalOrientation());
1007     }
1008 
1009     @Test
1010     @EnableCompatChanges({OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION})
testShouldUseDisplayLandscapeNaturalOrientation_portraitNaturalOrientation_returnsFalse()1011     public void testShouldUseDisplayLandscapeNaturalOrientation_portraitNaturalOrientation_returnsFalse() {
1012         prepareActivityThatShouldUseDisplayLandscapeNaturalOrientation();
1013         doReturn(ORIENTATION_PORTRAIT).when(mDisplayContent).getNaturalOrientation();
1014 
1015         assertFalse(mController.shouldUseDisplayLandscapeNaturalOrientation());
1016     }
1017 
1018     @Test
1019     @EnableCompatChanges({OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION})
testShouldUseDisplayLandscapeNaturalOrientation_disabledIgnoreOrientationRequest_returnsFalse()1020     public void testShouldUseDisplayLandscapeNaturalOrientation_disabledIgnoreOrientationRequest_returnsFalse() {
1021         prepareActivityThatShouldUseDisplayLandscapeNaturalOrientation();
1022         mDisplayContent.setIgnoreOrientationRequest(false);
1023 
1024         assertFalse(mController.shouldUseDisplayLandscapeNaturalOrientation());
1025     }
1026 
1027     @Test
1028     @EnableCompatChanges({OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION})
testShouldUseDisplayLandscapeNaturalOrientation_inMultiWindowMode_returnsFalse()1029     public void testShouldUseDisplayLandscapeNaturalOrientation_inMultiWindowMode_returnsFalse() {
1030         prepareActivityThatShouldUseDisplayLandscapeNaturalOrientation();
1031 
1032         spyOn(mTask);
1033         doReturn(true).when(mTask).inMultiWindowMode();
1034 
1035         assertFalse(mController.shouldUseDisplayLandscapeNaturalOrientation());
1036     }
1037 
1038     @Test
1039     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS})
testShouldSendFakeFocus_overrideEnabled_returnsTrue()1040     public void testShouldSendFakeFocus_overrideEnabled_returnsTrue() {
1041         doReturn(true).when(mLetterboxConfiguration).isCompatFakeFocusEnabled();
1042 
1043         mController = new LetterboxUiController(mWm, mActivity);
1044 
1045         assertTrue(mController.shouldSendFakeFocus());
1046     }
1047 
1048     @Test
1049     @DisableCompatChanges({OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS})
testShouldSendFakeFocus_overrideDisabled_returnsFalse()1050     public void testShouldSendFakeFocus_overrideDisabled_returnsFalse() {
1051         doReturn(true).when(mLetterboxConfiguration).isCompatFakeFocusEnabled();
1052 
1053         mController = new LetterboxUiController(mWm, mActivity);
1054 
1055         assertFalse(mController.shouldSendFakeFocus());
1056     }
1057 
1058     @Test
1059     @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS})
testIsCompatFakeFocusEnabled_propertyDisabledAndOverrideEnabled_fakeFocusDisabled()1060     public void testIsCompatFakeFocusEnabled_propertyDisabledAndOverrideEnabled_fakeFocusDisabled()
1061             throws Exception {
1062         doReturn(true).when(mLetterboxConfiguration).isCompatFakeFocusEnabled();
1063         mockThatProperty(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS, /* value */ false);
1064 
1065         mController = new LetterboxUiController(mWm, mActivity);
1066 
1067         assertFalse(mController.shouldSendFakeFocus());
1068     }
1069 
1070     @Test
1071     @DisableCompatChanges({OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS})
testIsCompatFakeFocusEnabled_propertyEnabled_noOverride_fakeFocusEnabled()1072     public void testIsCompatFakeFocusEnabled_propertyEnabled_noOverride_fakeFocusEnabled()
1073             throws Exception {
1074         doReturn(true).when(mLetterboxConfiguration).isCompatFakeFocusEnabled();
1075         mockThatProperty(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS, /* value */ true);
1076 
1077         mController = new LetterboxUiController(mWm, mActivity);
1078 
1079         assertTrue(mController.shouldSendFakeFocus());
1080     }
1081 
1082     @Test
testIsCompatFakeFocusEnabled_propertyDisabled_fakeFocusDisabled()1083     public void testIsCompatFakeFocusEnabled_propertyDisabled_fakeFocusDisabled()
1084             throws Exception {
1085         doReturn(true).when(mLetterboxConfiguration).isCompatFakeFocusEnabled();
1086         mockThatProperty(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS, /* value */ false);
1087 
1088         mController = new LetterboxUiController(mWm, mActivity);
1089 
1090         assertFalse(mController.shouldSendFakeFocus());
1091     }
1092 
1093     @Test
testIsCompatFakeFocusEnabled_propertyEnabled_fakeFocusEnabled()1094     public void testIsCompatFakeFocusEnabled_propertyEnabled_fakeFocusEnabled()
1095             throws Exception {
1096         doReturn(true).when(mLetterboxConfiguration).isCompatFakeFocusEnabled();
1097         mockThatProperty(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS, /* value */ true);
1098 
1099         mController = new LetterboxUiController(mWm, mActivity);
1100 
1101         assertTrue(mController.shouldSendFakeFocus());
1102     }
1103 
1104     @Test
1105     @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
testshouldOverrideMinAspectRatio_overrideEnabled_returnsTrue()1106     public void testshouldOverrideMinAspectRatio_overrideEnabled_returnsTrue() {
1107         mController = new LetterboxUiController(mWm, mActivity);
1108 
1109         assertTrue(mController.shouldOverrideMinAspectRatio());
1110     }
1111 
1112     @Test
1113     @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
testshouldOverrideMinAspectRatio_propertyTrue_overrideEnabled_returnsTrue()1114     public void testshouldOverrideMinAspectRatio_propertyTrue_overrideEnabled_returnsTrue()
1115             throws Exception {
1116         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
1117         mController = new LetterboxUiController(mWm, mActivity);
1118 
1119         assertTrue(mController.shouldOverrideMinAspectRatio());
1120     }
1121 
1122     @Test
1123     @DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
testshouldOverrideMinAspectRatio_propertyTrue_overrideDisabled_returnsFalse()1124     public void testshouldOverrideMinAspectRatio_propertyTrue_overrideDisabled_returnsFalse()
1125             throws Exception {
1126         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
1127         mController = new LetterboxUiController(mWm, mActivity);
1128 
1129         assertFalse(mController.shouldOverrideMinAspectRatio());
1130     }
1131 
1132     @Test
1133     @DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
testshouldOverrideMinAspectRatio_overrideDisabled_returnsFalse()1134     public void testshouldOverrideMinAspectRatio_overrideDisabled_returnsFalse() {
1135         mController = new LetterboxUiController(mWm, mActivity);
1136 
1137         assertFalse(mController.shouldOverrideMinAspectRatio());
1138     }
1139 
1140     @Test
1141     @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
testshouldOverrideMinAspectRatio_propertyFalse_overrideEnabled_returnsFalse()1142     public void testshouldOverrideMinAspectRatio_propertyFalse_overrideEnabled_returnsFalse()
1143             throws Exception {
1144         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
1145         mController = new LetterboxUiController(mWm, mActivity);
1146 
1147         assertFalse(mController.shouldOverrideMinAspectRatio());
1148     }
1149 
1150     @Test
1151     @DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
testshouldOverrideMinAspectRatio_propertyFalse_noOverride_returnsFalse()1152     public void testshouldOverrideMinAspectRatio_propertyFalse_noOverride_returnsFalse()
1153             throws Exception {
1154         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
1155         mController = new LetterboxUiController(mWm, mActivity);
1156 
1157         assertFalse(mController.shouldOverrideMinAspectRatio());
1158     }
1159 
1160     @Test
1161     @EnableCompatChanges({FORCE_RESIZE_APP})
testshouldOverrideForceResizeApp_overrideEnabled_returnsTrue()1162     public void testshouldOverrideForceResizeApp_overrideEnabled_returnsTrue() {
1163         mController = new LetterboxUiController(mWm, mActivity);
1164 
1165         assertTrue(mController.shouldOverrideForceResizeApp());
1166     }
1167 
1168     @Test
1169     @EnableCompatChanges({FORCE_RESIZE_APP})
testshouldOverrideForceResizeApp_propertyTrue_overrideEnabled_returnsTrue()1170     public void testshouldOverrideForceResizeApp_propertyTrue_overrideEnabled_returnsTrue()
1171             throws Exception {
1172         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ true);
1173         mController = new LetterboxUiController(mWm, mActivity);
1174 
1175         assertTrue(mController.shouldOverrideForceResizeApp());
1176     }
1177 
1178     @Test
1179     @DisableCompatChanges({FORCE_RESIZE_APP})
testshouldOverrideForceResizeApp_propertyTrue_overrideDisabled_returnsFalse()1180     public void testshouldOverrideForceResizeApp_propertyTrue_overrideDisabled_returnsFalse()
1181             throws Exception {
1182         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ true);
1183         mController = new LetterboxUiController(mWm, mActivity);
1184 
1185         assertFalse(mController.shouldOverrideForceResizeApp());
1186     }
1187 
1188     @Test
1189     @DisableCompatChanges({FORCE_RESIZE_APP})
testshouldOverrideForceResizeApp_overrideDisabled_returnsFalse()1190     public void testshouldOverrideForceResizeApp_overrideDisabled_returnsFalse() {
1191         mController = new LetterboxUiController(mWm, mActivity);
1192 
1193         assertFalse(mController.shouldOverrideForceResizeApp());
1194     }
1195 
1196     @Test
1197     @EnableCompatChanges({FORCE_RESIZE_APP})
testshouldOverrideForceResizeApp_propertyFalse_overrideEnabled_returnsFalse()1198     public void testshouldOverrideForceResizeApp_propertyFalse_overrideEnabled_returnsFalse()
1199             throws Exception {
1200         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
1201         mController = new LetterboxUiController(mWm, mActivity);
1202 
1203         assertFalse(mController.shouldOverrideForceResizeApp());
1204     }
1205 
1206     @Test
1207     @DisableCompatChanges({FORCE_RESIZE_APP})
testshouldOverrideForceResizeApp_propertyFalse_noOverride_returnsFalse()1208     public void testshouldOverrideForceResizeApp_propertyFalse_noOverride_returnsFalse()
1209             throws Exception {
1210         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
1211         mController = new LetterboxUiController(mWm, mActivity);
1212 
1213         assertFalse(mController.shouldOverrideForceResizeApp());
1214     }
1215 
1216     @Test
1217     @EnableCompatChanges({FORCE_NON_RESIZE_APP})
testshouldOverrideForceNonResizeApp_overrideEnabled_returnsTrue()1218     public void testshouldOverrideForceNonResizeApp_overrideEnabled_returnsTrue() {
1219         mController = new LetterboxUiController(mWm, mActivity);
1220 
1221         assertTrue(mController.shouldOverrideForceNonResizeApp());
1222     }
1223 
1224     @Test
1225     @EnableCompatChanges({FORCE_NON_RESIZE_APP})
testshouldOverrideForceNonResizeApp_propertyTrue_overrideEnabled_returnsTrue()1226     public void testshouldOverrideForceNonResizeApp_propertyTrue_overrideEnabled_returnsTrue()
1227             throws Exception {
1228         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ true);
1229         mController = new LetterboxUiController(mWm, mActivity);
1230 
1231         assertTrue(mController.shouldOverrideForceNonResizeApp());
1232     }
1233 
1234     @Test
1235     @DisableCompatChanges({FORCE_NON_RESIZE_APP})
testshouldOverrideForceNonResizeApp_propertyTrue_overrideDisabled_returnsFalse()1236     public void testshouldOverrideForceNonResizeApp_propertyTrue_overrideDisabled_returnsFalse()
1237             throws Exception {
1238         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ true);
1239         mController = new LetterboxUiController(mWm, mActivity);
1240 
1241         assertFalse(mController.shouldOverrideForceNonResizeApp());
1242     }
1243 
1244     @Test
1245     @DisableCompatChanges({FORCE_NON_RESIZE_APP})
testshouldOverrideForceNonResizeApp_overrideDisabled_returnsFalse()1246     public void testshouldOverrideForceNonResizeApp_overrideDisabled_returnsFalse() {
1247         mController = new LetterboxUiController(mWm, mActivity);
1248 
1249         assertFalse(mController.shouldOverrideForceNonResizeApp());
1250     }
1251 
1252     @Test
1253     @EnableCompatChanges({FORCE_NON_RESIZE_APP})
testshouldOverrideForceNonResizeApp_propertyFalse_overrideEnabled_returnsFalse()1254     public void testshouldOverrideForceNonResizeApp_propertyFalse_overrideEnabled_returnsFalse()
1255             throws Exception {
1256         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
1257         mController = new LetterboxUiController(mWm, mActivity);
1258 
1259         assertFalse(mController.shouldOverrideForceNonResizeApp());
1260     }
1261 
1262     @Test
1263     @DisableCompatChanges({FORCE_NON_RESIZE_APP})
testshouldOverrideForceNonResizeApp_propertyFalse_noOverride_returnsFalse()1264     public void testshouldOverrideForceNonResizeApp_propertyFalse_noOverride_returnsFalse()
1265             throws Exception {
1266         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
1267         mController = new LetterboxUiController(mWm, mActivity);
1268 
1269         assertFalse(mController.shouldOverrideForceNonResizeApp());
1270     }
1271 
1272     @Test
testgetFixedOrientationLetterboxAspectRatio_splitScreenAspectEnabled()1273     public void testgetFixedOrientationLetterboxAspectRatio_splitScreenAspectEnabled() {
1274         doReturn(true).when(mActivity.mWmService.mLetterboxConfiguration)
1275                 .isCameraCompatTreatmentEnabled();
1276         doReturn(true).when(mActivity.mWmService.mLetterboxConfiguration)
1277                 .isCameraCompatTreatmentEnabledAtBuildTime();
1278         doReturn(true).when(mActivity.mWmService.mLetterboxConfiguration)
1279                 .isCameraCompatSplitScreenAspectRatioEnabled();
1280         doReturn(false).when(mActivity.mWmService.mLetterboxConfiguration)
1281                 .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox();
1282         doReturn(1.5f).when(mActivity.mWmService.mLetterboxConfiguration)
1283                 .getFixedOrientationLetterboxAspectRatio();
1284 
1285         // Recreate DisplayContent with DisplayRotationCompatPolicy
1286         mActivity = setUpActivityWithComponent();
1287         mController = new LetterboxUiController(mWm, mActivity);
1288 
1289         assertEquals(mController.getFixedOrientationLetterboxAspectRatio(
1290                 mActivity.getParent().getConfiguration()), 1.5f, /* delta */ 0.01);
1291 
1292         spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
1293         doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
1294                 .isTreatmentEnabledForActivity(eq(mActivity));
1295 
1296         assertEquals(mController.getFixedOrientationLetterboxAspectRatio(
1297                 mActivity.getParent().getConfiguration()), mController.getSplitScreenAspectRatio(),
1298                 /* delta */  0.01);
1299     }
1300 
mockThatProperty(String propertyName, boolean value)1301     private void mockThatProperty(String propertyName, boolean value) throws Exception {
1302         Property property = new Property(propertyName, /* value */ value, /* packageName */ "",
1303                  /* className */ "");
1304         PackageManager pm = mWm.mContext.getPackageManager();
1305         spyOn(pm);
1306         doReturn(property).when(pm).getProperty(eq(propertyName), anyString());
1307     }
1308 
prepareActivityThatShouldUseDisplayLandscapeNaturalOrientation()1309     private void prepareActivityThatShouldUseDisplayLandscapeNaturalOrientation() {
1310         spyOn(mDisplayContent);
1311         doReturn(ORIENTATION_LANDSCAPE).when(mDisplayContent).getNaturalOrientation();
1312         mDisplayContent.setIgnoreOrientationRequest(true);
1313     }
1314 
prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch()1315     private void prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch() {
1316         doReturn(true).when(mLetterboxConfiguration)
1317                 .isPolicyForIgnoringRequestedOrientationEnabled();
1318         mController.setRelaunchingAfterRequestedOrientationChanged(true);
1319     }
1320 
setUpActivityWithComponent()1321     private ActivityRecord setUpActivityWithComponent() {
1322         mDisplayContent = new TestDisplayContent
1323                 .Builder(mAtm, /* dw */ 1000, /* dh */ 2000).build();
1324         mTask = new TaskBuilder(mSupervisor).setDisplay(mDisplayContent).build();
1325         final ActivityRecord activity = new ActivityBuilder(mAtm)
1326                 .setOnTop(true)
1327                 .setTask(mTask)
1328                 // Set the component to be that of the test class in order to enable compat changes
1329                 .setComponent(ComponentName.createRelative(mContext,
1330                         com.android.server.wm.LetterboxUiControllerTest.class.getName()))
1331                 .build();
1332         return activity;
1333     }
1334 }
1335