1 /*
2  * Copyright (C) 2018 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.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
20 import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
21 import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DISABLED;
22 import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED;
23 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
24 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
25 import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
26 import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
27 
28 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
29 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
30 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
31 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
32 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
33 
34 import static org.junit.Assert.assertEquals;
35 import static org.junit.Assert.assertFalse;
36 import static org.junit.Assert.assertNotEquals;
37 import static org.junit.Assert.assertTrue;
38 import static org.mockito.ArgumentMatchers.any;
39 import static org.mockito.ArgumentMatchers.anyInt;
40 import static org.mockito.Matchers.eq;
41 
42 import android.annotation.NonNull;
43 import android.app.WindowConfiguration;
44 import android.content.ContentResolver;
45 import android.platform.test.annotations.Presubmit;
46 import android.provider.Settings;
47 import android.view.Display;
48 import android.view.DisplayInfo;
49 import android.view.Surface;
50 
51 import androidx.test.filters.SmallTest;
52 
53 import com.android.server.LocalServices;
54 import com.android.server.policy.WindowManagerPolicy;
55 import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
56 
57 import org.junit.Before;
58 import org.junit.Test;
59 import org.junit.runner.RunWith;
60 
61 import java.util.HashMap;
62 import java.util.Map;
63 
64 /**
65  * Tests for the {@link DisplayWindowSettings} class.
66  *
67  * Build/Install/Run:
68  *  atest WmTests:DisplayWindowSettingsTests
69  */
70 @SmallTest
71 @Presubmit
72 @WindowTestsBase.UseTestDisplay
73 @RunWith(WindowTestRunner.class)
74 public class DisplayWindowSettingsTests extends WindowTestsBase {
75     private TestSettingsProvider mSettingsProvider;
76     private DisplayWindowSettings mDisplayWindowSettings;
77 
78     private DisplayInfo mPrivateDisplayInfo;
79 
80     private DisplayContent mPrimaryDisplay;
81     private DisplayContent mSecondaryDisplay;
82     private DisplayContent mPrivateDisplay;
83 
84     @Before
setUp()85     public void setUp() throws Exception {
86         // TODO(b/121296525): We may want to restore other display settings (not only overscans in
87         // testPersistOverscan*test) on mPrimaryDisplay and mSecondaryDisplay back to default
88         // values after each test finishes, since we are going to reuse a singleton
89         // WindowManagerService instance among all tests that extend {@link WindowTestsBase} class
90         // (b/113239988).
91         mWm.mAtmService.mSupportsFreeformWindowManagement = false;
92         mWm.setIsPc(false);
93         mWm.setForceDesktopModeOnExternalDisplays(false);
94 
95         mSettingsProvider = new TestSettingsProvider();
96         mDisplayWindowSettings = new DisplayWindowSettings(mWm, mSettingsProvider);
97 
98         mPrimaryDisplay = mWm.getDefaultDisplayContentLocked();
99         mSecondaryDisplay = mDisplayContent;
100         assertNotEquals(Display.DEFAULT_DISPLAY, mSecondaryDisplay.getDisplayId());
101 
102         mPrivateDisplayInfo = new DisplayInfo(mDisplayInfo);
103         mPrivateDisplayInfo.flags |= Display.FLAG_PRIVATE;
104         mPrivateDisplay = createNewDisplay(mPrivateDisplayInfo);
105         assertNotEquals(Display.DEFAULT_DISPLAY, mPrivateDisplay.getDisplayId());
106         assertNotEquals(mSecondaryDisplay.getDisplayId(), mPrivateDisplay.getDisplayId());
107     }
108 
109     @Test
testPrimaryDisplayDefaultToFullscreen_NoFreeformSupport()110     public void testPrimaryDisplayDefaultToFullscreen_NoFreeformSupport() {
111         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
112 
113         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
114                 mPrimaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
115     }
116 
117     @Test
testPrimaryDisplayDefaultToFullscreen_HasFreeformSupport_NonPc_NoDesktopMode()118     public void testPrimaryDisplayDefaultToFullscreen_HasFreeformSupport_NonPc_NoDesktopMode() {
119         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
120 
121         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
122 
123         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
124                 mPrimaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
125     }
126 
127     @Test
testPrimaryDisplayDefaultToFullscreen_HasFreeformSupport_NonPc_HasDesktopMode()128     public void testPrimaryDisplayDefaultToFullscreen_HasFreeformSupport_NonPc_HasDesktopMode() {
129         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
130         mWm.setForceDesktopModeOnExternalDisplays(true);
131 
132         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
133 
134         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
135                 mPrimaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
136     }
137 
138     @Test
testPrimaryDisplayDefaultToFreeform_HasFreeformSupport_IsPc()139     public void testPrimaryDisplayDefaultToFreeform_HasFreeformSupport_IsPc() {
140         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
141         mWm.setIsPc(true);
142 
143         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
144 
145         assertEquals(WINDOWING_MODE_FREEFORM,
146                 mPrimaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
147     }
148 
149     @Test
testPrimaryDisplayUpdateToFreeform_HasFreeformSupport_IsPc()150     public void testPrimaryDisplayUpdateToFreeform_HasFreeformSupport_IsPc() {
151         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
152 
153         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
154         mWm.setIsPc(true);
155 
156         mDisplayWindowSettings.updateSettingsForDisplay(mPrimaryDisplay);
157 
158         assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
159                 mPrimaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
160     }
161 
162     @Test
testSecondaryDisplayDefaultToFullscreen_NoFreeformSupport()163     public void testSecondaryDisplayDefaultToFullscreen_NoFreeformSupport() {
164         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
165 
166         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
167                 mSecondaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
168     }
169 
170     @Test
testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_NonPc_NoDesktopMode()171     public void testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_NonPc_NoDesktopMode() {
172         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
173 
174         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
175 
176         assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
177                 mSecondaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
178     }
179 
180     @Test
testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_NonPc_HasDesktopMode()181     public void testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_NonPc_HasDesktopMode() {
182         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
183         mWm.setForceDesktopModeOnExternalDisplays(true);
184 
185         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
186 
187         assertEquals(WINDOWING_MODE_FREEFORM,
188                 mSecondaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
189     }
190 
191     @Test
testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_IsPc()192     public void testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_IsPc() {
193         mWm.mAtmService.mSupportsFreeformWindowManagement = true;
194         mWm.setIsPc(true);
195 
196         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
197 
198         assertEquals(WINDOWING_MODE_FREEFORM,
199                 mSecondaryDisplay.getDefaultTaskDisplayArea().getWindowingMode());
200     }
201 
202     @Test
testDefaultToOriginalMetrics()203     public void testDefaultToOriginalMetrics() {
204         final int originalWidth = mSecondaryDisplay.mBaseDisplayWidth;
205         final int originalHeight = mSecondaryDisplay.mBaseDisplayHeight;
206         final int originalDensity = mSecondaryDisplay.mBaseDisplayDensity;
207         final boolean originalScalingDisabled = mSecondaryDisplay.mDisplayScalingDisabled;
208 
209         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
210 
211         assertEquals(originalWidth, mSecondaryDisplay.mBaseDisplayWidth);
212         assertEquals(originalHeight, mSecondaryDisplay.mBaseDisplayHeight);
213         assertEquals(originalDensity, mSecondaryDisplay.mBaseDisplayDensity);
214         assertEquals(originalScalingDisabled, mSecondaryDisplay.mDisplayScalingDisabled);
215     }
216 
217     @Test
testSetForcedSize()218     public void testSetForcedSize() {
219         final DisplayInfo originalInfo = new DisplayInfo(mSecondaryDisplay.getDisplayInfo());
220         // Provides the orginal display info to avoid changing initial display size.
221         doAnswer(invocation -> {
222             ((DisplayInfo) invocation.getArguments()[1]).copyFrom(originalInfo);
223             return null;
224         }).when(mWm.mDisplayManagerInternal).getNonOverrideDisplayInfo(anyInt(), any());
225 
226         mDisplayWindowSettings.setForcedSize(mSecondaryDisplay, 1000 /* width */,
227                 2000 /* height */);
228         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
229 
230         assertEquals(1000 /* width */, mSecondaryDisplay.mBaseDisplayWidth);
231         assertEquals(2000 /* height */, mSecondaryDisplay.mBaseDisplayHeight);
232 
233         mWm.clearForcedDisplaySize(mSecondaryDisplay.getDisplayId());
234         assertEquals(mSecondaryDisplay.mInitialDisplayWidth, mSecondaryDisplay.mBaseDisplayWidth);
235         assertEquals(mSecondaryDisplay.mInitialDisplayHeight, mSecondaryDisplay.mBaseDisplayHeight);
236     }
237 
238     @Test
testSetForcedDensity()239     public void testSetForcedDensity() {
240         mDisplayWindowSettings.setForcedDensity(mSecondaryDisplay.getDisplayInfo(),
241                 600 /* density */, 0 /* userId */);
242         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
243 
244         assertEquals(600 /* density */, mSecondaryDisplay.mBaseDisplayDensity);
245 
246         mWm.clearForcedDisplayDensityForUser(mSecondaryDisplay.getDisplayId(), 0 /* userId */);
247         assertEquals(mSecondaryDisplay.mInitialDisplayDensity,
248                 mSecondaryDisplay.mBaseDisplayDensity);
249     }
250 
251     @Test
testSetForcedScalingMode()252     public void testSetForcedScalingMode() {
253         mDisplayWindowSettings.setForcedScalingMode(mSecondaryDisplay,
254                 DisplayContent.FORCE_SCALING_MODE_DISABLED);
255         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
256 
257         assertTrue(mSecondaryDisplay.mDisplayScalingDisabled);
258 
259         mWm.setForcedDisplayScalingMode(mSecondaryDisplay.getDisplayId(),
260                 DisplayContent.FORCE_SCALING_MODE_AUTO);
261         assertFalse(mSecondaryDisplay.mDisplayScalingDisabled);
262     }
263 
264     @Test
testResetAllowAllRotations()265     public void testResetAllowAllRotations() {
266         final DisplayRotation displayRotation = mock(DisplayRotation.class);
267         spyOn(mPrimaryDisplay);
268         doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation();
269 
270         mDisplayWindowSettings.applyRotationSettingsToDisplayLocked(mPrimaryDisplay);
271 
272         verify(displayRotation).resetAllowAllRotations();
273     }
274 
275     @Test
testDefaultToFreeUserRotation()276     public void testDefaultToFreeUserRotation() {
277         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
278 
279         final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
280         assertEquals(WindowManagerPolicy.USER_ROTATION_FREE, rotation.getUserRotationMode());
281         assertFalse(rotation.isRotationFrozen());
282     }
283 
284     @Test
testDefaultTo0DegRotation()285     public void testDefaultTo0DegRotation() {
286         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
287 
288         assertEquals(Surface.ROTATION_0, mSecondaryDisplay.getDisplayRotation().getUserRotation());
289     }
290 
291     @Test
testPrivateDisplayDefaultToDestroyContent()292     public void testPrivateDisplayDefaultToDestroyContent() {
293         assertEquals(REMOVE_CONTENT_MODE_DESTROY,
294                 mDisplayWindowSettings.getRemoveContentModeLocked(mPrivateDisplay));
295     }
296 
297     @Test
testPublicDisplayDefaultToMoveToPrimary()298     public void testPublicDisplayDefaultToMoveToPrimary() {
299         assertEquals(REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY,
300                 mDisplayWindowSettings.getRemoveContentModeLocked(mSecondaryDisplay));
301     }
302 
303     @Test
testDefaultToNotShowWithInsecureKeyguard()304     public void testDefaultToNotShowWithInsecureKeyguard() {
305         assertFalse(mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(mPrivateDisplay));
306         assertFalse(mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(mSecondaryDisplay));
307     }
308 
309     @Test(expected = IllegalArgumentException.class)
testPublicDisplayNotAllowSetShouldShowWithInsecureKeyguard()310     public void testPublicDisplayNotAllowSetShouldShowWithInsecureKeyguard() {
311         mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(mSecondaryDisplay, true);
312     }
313 
314     @Test
testPrivateDisplayAllowSetShouldShowWithInsecureKeyguard()315     public void testPrivateDisplayAllowSetShouldShowWithInsecureKeyguard() {
316         mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(mPrivateDisplay, true);
317 
318         assertTrue(mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(mPrivateDisplay));
319     }
320 
321     @Test
testPrimaryDisplayShouldShowSystemDecors()322     public void testPrimaryDisplayShouldShowSystemDecors() {
323         assertTrue(mDisplayWindowSettings.shouldShowSystemDecorsLocked(mPrimaryDisplay));
324 
325         mDisplayWindowSettings.setShouldShowSystemDecorsLocked(mPrimaryDisplay, false);
326 
327         // Default display should show system decors
328         assertTrue(mDisplayWindowSettings.shouldShowSystemDecorsLocked(mPrimaryDisplay));
329     }
330 
331     @Test
testSecondaryDisplayDefaultToNotShowSystemDecors()332     public void testSecondaryDisplayDefaultToNotShowSystemDecors() {
333         assertFalse(mDisplayWindowSettings.shouldShowSystemDecorsLocked(mSecondaryDisplay));
334     }
335 
336     @Test
testPrimaryDisplayImePolicy()337     public void testPrimaryDisplayImePolicy() {
338         assertEquals(DISPLAY_IME_POLICY_LOCAL,
339                 mDisplayWindowSettings.getImePolicyLocked(mPrimaryDisplay));
340 
341         mDisplayWindowSettings.setDisplayImePolicy(mPrimaryDisplay,
342                 DISPLAY_IME_POLICY_FALLBACK_DISPLAY);
343 
344         assertEquals(DISPLAY_IME_POLICY_LOCAL,
345                 mDisplayWindowSettings.getImePolicyLocked(mPrimaryDisplay));
346     }
347 
348     @Test
testSecondaryDisplayDefaultToShowImeOnFallbackDisplay()349     public void testSecondaryDisplayDefaultToShowImeOnFallbackDisplay() {
350         assertEquals(DISPLAY_IME_POLICY_FALLBACK_DISPLAY,
351                 mDisplayWindowSettings.getImePolicyLocked(mSecondaryDisplay));
352     }
353 
354     @Test
testSetUserRotationMode()355     public void testSetUserRotationMode() {
356         mDisplayWindowSettings.setUserRotation(mSecondaryDisplay,
357                 WindowManagerPolicy.USER_ROTATION_LOCKED, Surface.ROTATION_90);
358 
359         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
360 
361         final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
362         assertEquals(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation.getUserRotationMode());
363         assertTrue(rotation.isRotationFrozen());
364     }
365 
366     @Test
testSetUserRotation()367     public void testSetUserRotation() {
368         mDisplayWindowSettings.setUserRotation(mSecondaryDisplay,
369                 WindowManagerPolicy.USER_ROTATION_LOCKED, Surface.ROTATION_90);
370 
371         mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);
372 
373         assertEquals(Surface.ROTATION_90, mSecondaryDisplay.getDisplayRotation().getUserRotation());
374     }
375 
376     @Test
testFixedToUserRotationDefault()377     public void testFixedToUserRotationDefault() {
378         mDisplayWindowSettings.setUserRotation(mPrimaryDisplay,
379                 WindowManagerPolicy.USER_ROTATION_LOCKED, Surface.ROTATION_0);
380 
381         final DisplayRotation displayRotation = mock(DisplayRotation.class);
382         spyOn(mPrimaryDisplay);
383         doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation();
384 
385         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
386 
387         verify(displayRotation).restoreSettings(anyInt(), anyInt(),
388                 eq(FIXED_TO_USER_ROTATION_DEFAULT));
389     }
390 
391     @Test
testSetFixedToUserRotationDisabled()392     public void testSetFixedToUserRotationDisabled() {
393         mDisplayWindowSettings.setFixedToUserRotation(mPrimaryDisplay,
394                 FIXED_TO_USER_ROTATION_DISABLED);
395 
396         final DisplayRotation displayRotation = mock(DisplayRotation.class);
397         spyOn(mPrimaryDisplay);
398         doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation();
399 
400         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
401 
402         verify(displayRotation).restoreSettings(anyInt(), anyInt(),
403                 eq(FIXED_TO_USER_ROTATION_DISABLED));
404     }
405 
406     @Test
testSetFixedToUserRotationEnabled()407     public void testSetFixedToUserRotationEnabled() {
408         mDisplayWindowSettings.setFixedToUserRotation(mPrimaryDisplay,
409                 FIXED_TO_USER_ROTATION_ENABLED);
410 
411         final DisplayRotation displayRotation = mock(DisplayRotation.class);
412         spyOn(mPrimaryDisplay);
413         doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation();
414 
415         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
416 
417         verify(displayRotation).restoreSettings(anyInt(), anyInt(),
418                 eq(FIXED_TO_USER_ROTATION_ENABLED));
419     }
420 
421     @Test
testShouldShowImeOnDisplayWithinForceDesktopMode()422     public void testShouldShowImeOnDisplayWithinForceDesktopMode() {
423         try {
424             // Presume display enabled force desktop mode from developer options.
425             final DisplayContent dc = createMockSimulatedDisplay();
426             mWm.setForceDesktopModeOnExternalDisplays(true);
427             final WindowManagerInternal wmInternal = LocalServices.getService(
428                     WindowManagerInternal.class);
429             // Make sure WindowManagerInter#getDisplayImePolicy is SHOW_IME_ON_DISPLAY is due to
430             // mForceDesktopModeOnExternalDisplays being SHOW_IME_ON_DISPLAY.
431             assertEquals(DISPLAY_IME_POLICY_FALLBACK_DISPLAY,
432                     mWm.mDisplayWindowSettings.getImePolicyLocked(dc));
433             assertEquals(DISPLAY_IME_POLICY_LOCAL, wmInternal.getDisplayImePolicy(dc.getDisplayId()));
434         } finally {
435             mWm.setForceDesktopModeOnExternalDisplays(false);
436         }
437     }
438 
439     @Test
testDisplayWindowSettingsAppliedOnDisplayReady()440     public void testDisplayWindowSettingsAppliedOnDisplayReady() {
441         // Set forced densities for two displays in DisplayWindowSettings
442         final DisplayContent dc = createMockSimulatedDisplay();
443         final ContentResolver contentResolver = useFakeSettingsProvider();
444         mDisplayWindowSettings.setForcedDensity(mPrimaryDisplay.getDisplayInfo(), 123,
445                 0 /* userId */);
446         mDisplayWindowSettings.setForcedDensity(dc.getDisplayInfo(), 456, 0 /* userId */);
447 
448         // Apply settings to displays - the settings will be stored, but config will not be
449         // recalculated immediately.
450         mDisplayWindowSettings.applySettingsToDisplayLocked(mPrimaryDisplay);
451         mDisplayWindowSettings.applySettingsToDisplayLocked(dc);
452         assertFalse(mPrimaryDisplay.mWaitingForConfig);
453         assertFalse(dc.mWaitingForConfig);
454 
455         final int invalidW = Integer.MAX_VALUE;
456         final int invalidH = Integer.MAX_VALUE;
457         // Verify that applyForcedPropertiesForDefaultDisplay() handles invalid size request.
458         Settings.Global.putString(contentResolver, Settings.Global.DISPLAY_SIZE_FORCED,
459                 invalidW + "," + invalidH);
460         // Notify WM that the displays are ready and check that they are reconfigured.
461         mWm.displayReady();
462         waitUntilHandlersIdle();
463 
464         // Density is set successfully.
465         assertEquals(123, mPrimaryDisplay.getConfiguration().densityDpi);
466         assertEquals(456, dc.getConfiguration().densityDpi);
467         // Invalid size won't be applied.
468         assertNotEquals(invalidW, mPrimaryDisplay.mBaseDisplayWidth);
469         assertNotEquals(invalidH, mPrimaryDisplay.mBaseDisplayHeight);
470     }
471 
472     @Test
testDisplayRotationSettingsAppliedOnCreation()473     public void testDisplayRotationSettingsAppliedOnCreation() {
474         // Create new displays with different rotation settings
475         final SettingsEntry settingsEntry1 = new SettingsEntry();
476         settingsEntry1.mIgnoreOrientationRequest = false;
477         final DisplayContent dcDontIgnoreOrientation = createMockSimulatedDisplay(settingsEntry1);
478         final SettingsEntry settingsEntry2 = new SettingsEntry();
479         settingsEntry2.mIgnoreOrientationRequest = true;
480         final DisplayContent dcIgnoreOrientation = createMockSimulatedDisplay(settingsEntry2);
481 
482         // Verify that newly created displays are created with correct rotation settings
483         assertFalse(dcDontIgnoreOrientation.getIgnoreOrientationRequest());
484         assertTrue(dcIgnoreOrientation.getIgnoreOrientationRequest());
485     }
486 
487     public final class TestSettingsProvider implements DisplayWindowSettings.SettingsProvider {
488         Map<DisplayInfo, SettingsEntry> mOverrideSettingsCache = new HashMap<>();
489 
490         @Override
getSettings(@onNull DisplayInfo info)491         public SettingsEntry getSettings(@NonNull DisplayInfo info) {
492             return getOverrideSettings(info);
493         }
494 
495         @Override
getOverrideSettings(@onNull DisplayInfo info)496         public SettingsEntry getOverrideSettings(@NonNull DisplayInfo info) {
497             SettingsEntry result = new SettingsEntry();
498             SettingsEntry overrideSettings = mOverrideSettingsCache.get(info);
499             if (overrideSettings != null) {
500                 result.setTo(overrideSettings);
501             }
502             return result;
503         }
504 
505         @Override
updateOverrideSettings(@onNull DisplayInfo info, @NonNull SettingsEntry settings)506         public void updateOverrideSettings(@NonNull DisplayInfo info,
507                 @NonNull SettingsEntry settings) {
508             SettingsEntry overrideSettings = mOverrideSettingsCache.get(info);
509             if (overrideSettings == null) {
510                 overrideSettings = new SettingsEntry();
511                 mOverrideSettingsCache.put(info, overrideSettings);
512             }
513 
514             overrideSettings.setTo(settings);
515         }
516     }
517 }
518