• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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.view.Display.REMOVE_MODE_DESTROY_CONTENT;
20 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
21 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
22 import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
23 import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
24 import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
25 
26 import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_AUTO;
27 import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_DISABLED;
28 
29 import android.annotation.NonNull;
30 import android.annotation.Nullable;
31 import android.app.WindowConfiguration;
32 import android.provider.Settings;
33 import android.view.Display;
34 import android.view.DisplayInfo;
35 import android.view.IWindowManager;
36 import android.view.Surface;
37 import android.view.WindowManager;
38 import android.view.WindowManager.DisplayImePolicy;
39 import android.window.DesktopExperienceFlags;
40 
41 import com.android.server.policy.WindowManagerPolicy;
42 import com.android.server.wm.DisplayContent.ForceScalingMode;
43 
44 import java.util.Objects;
45 
46 /**
47  * Current persistent settings about a display. Provides policies for display settings and
48  * delegates the persistence and lookup of settings values to the supplied {@link SettingsProvider}.
49  */
50 class DisplayWindowSettings {
51     @NonNull
52     private final WindowManagerService mService;
53     @NonNull
54     private final SettingsProvider mSettingsProvider;
55 
DisplayWindowSettings(@onNull WindowManagerService service, @NonNull SettingsProvider settingsProvider)56     DisplayWindowSettings(@NonNull WindowManagerService service,
57             @NonNull SettingsProvider settingsProvider) {
58         mService = service;
59         mSettingsProvider = settingsProvider;
60     }
61 
setUserRotation(@onNull DisplayContent displayContent, @WindowManagerPolicy.UserRotationMode int rotationMode, @Surface.Rotation int rotation)62     void setUserRotation(@NonNull DisplayContent displayContent,
63             @WindowManagerPolicy.UserRotationMode int rotationMode,
64             @Surface.Rotation int rotation) {
65         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
66         final SettingsProvider.SettingsEntry overrideSettings =
67                 mSettingsProvider.getOverrideSettings(displayInfo);
68         overrideSettings.mUserRotationMode = rotationMode;
69         overrideSettings.mUserRotation = rotation;
70         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
71     }
72 
73     /** Stores the size override settings. If the width or height is zero, it means to clear. */
setForcedSize(@onNull DisplayContent displayContent, int width, int height)74     void setForcedSize(@NonNull DisplayContent displayContent, int width, int height) {
75         if (displayContent.isDefaultDisplay) {
76             final String sizeString = (width == 0 || height == 0) ? "" : (width + "," + height);
77             Settings.Global.putString(mService.mContext.getContentResolver(),
78                     Settings.Global.DISPLAY_SIZE_FORCED, sizeString);
79         }
80 
81         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
82         final SettingsProvider.SettingsEntry overrideSettings =
83                 mSettingsProvider.getOverrideSettings(displayInfo);
84         overrideSettings.mForcedWidth = width;
85         overrideSettings.mForcedHeight = height;
86         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
87     }
88 
setForcedDensity(@onNull DisplayInfo info, int density, int userId)89     void setForcedDensity(@NonNull DisplayInfo info, int density, int userId) {
90         if (info.displayId == Display.DEFAULT_DISPLAY) {
91             final String densityString = density == 0 ? "" : Integer.toString(density);
92             Settings.Secure.putStringForUser(mService.mContext.getContentResolver(),
93                     Settings.Secure.DISPLAY_DENSITY_FORCED, densityString, userId);
94         }
95 
96         final SettingsProvider.SettingsEntry overrideSettings =
97                 mSettingsProvider.getOverrideSettings(info);
98         overrideSettings.mForcedDensity = density;
99         mSettingsProvider.updateOverrideSettings(info, overrideSettings);
100     }
101 
setForcedDensityRatio(@onNull DisplayInfo info, float ratio)102     void setForcedDensityRatio(@NonNull DisplayInfo info, float ratio) {
103         final SettingsProvider.SettingsEntry overrideSettings =
104                 mSettingsProvider.getOverrideSettings(info);
105         overrideSettings.mForcedDensityRatio = ratio;
106         mSettingsProvider.updateOverrideSettings(info, overrideSettings);
107     }
108 
setForcedScalingMode(@onNull DisplayContent displayContent, @ForceScalingMode int mode)109     void setForcedScalingMode(@NonNull DisplayContent displayContent, @ForceScalingMode int mode) {
110         if (displayContent.isDefaultDisplay) {
111             Settings.Global.putInt(mService.mContext.getContentResolver(),
112                     Settings.Global.DISPLAY_SCALING_FORCE, mode);
113         }
114 
115         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
116         final SettingsProvider.SettingsEntry overrideSettings =
117                 mSettingsProvider.getOverrideSettings(displayInfo);
118         overrideSettings.mForcedScalingMode = mode;
119         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
120     }
121 
setFixedToUserRotation(@onNull DisplayContent displayContent, int fixedToUserRotation)122     void setFixedToUserRotation(@NonNull DisplayContent displayContent, int fixedToUserRotation) {
123         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
124         final SettingsProvider.SettingsEntry overrideSettings =
125                 mSettingsProvider.getOverrideSettings(displayInfo);
126         overrideSettings.mFixedToUserRotation = fixedToUserRotation;
127         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
128     }
129 
setIgnoreOrientationRequest(@onNull DisplayContent displayContent, @Nullable Boolean ignoreOrientationRequest)130     void setIgnoreOrientationRequest(@NonNull DisplayContent displayContent,
131             @Nullable Boolean ignoreOrientationRequest) {
132         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
133         final SettingsProvider.SettingsEntry overrideSettings =
134                 mSettingsProvider.getOverrideSettings(displayInfo);
135         overrideSettings.mIgnoreOrientationRequest = ignoreOrientationRequest;
136         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
137     }
138 
139     @WindowConfiguration.WindowingMode
getWindowingModeLocked(@onNull SettingsProvider.SettingsEntry settings, @NonNull DisplayContent dc)140     private int getWindowingModeLocked(@NonNull SettingsProvider.SettingsEntry settings,
141             @NonNull DisplayContent dc) {
142         final int windowingModeFromDisplaySettings = settings.mWindowingMode;
143         // This display used to be in freeform, but we don't support freeform anymore, so fall
144         // back to fullscreen.
145         if (windowingModeFromDisplaySettings == WindowConfiguration.WINDOWING_MODE_FREEFORM
146                 && !mService.mAtmService.mSupportsFreeformWindowManagement) {
147             return WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
148         }
149         if (windowingModeFromDisplaySettings != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
150             return windowingModeFromDisplaySettings;
151         }
152         // No record is present so use default windowing mode policy.
153         final boolean forceFreeForm = mService.mAtmService.mSupportsFreeformWindowManagement
154                 && (mService.mIsPc || dc.isPublicSecondaryDisplayWithDesktopModeForceEnabled());
155         if (forceFreeForm) {
156             return WindowConfiguration.WINDOWING_MODE_FREEFORM;
157         }
158         final int currentWindowingMode = dc.getDefaultTaskDisplayArea().getWindowingMode();
159         if (currentWindowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
160             // No record preset in settings + no mode set via the display area policy.
161             // Move to fullscreen as a fallback.
162             return WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
163         }
164         if (currentWindowingMode == WindowConfiguration.WINDOWING_MODE_FREEFORM) {
165             // Freeform was enabled before but disabled now, the TDA should now move to fullscreen.
166             return WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
167         }
168         return currentWindowingMode;
169     }
170 
171     @WindowConfiguration.WindowingMode
getWindowingModeLocked(@onNull DisplayContent dc)172     int getWindowingModeLocked(@NonNull DisplayContent dc) {
173         final DisplayInfo displayInfo = dc.getDisplayInfo();
174         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
175         return getWindowingModeLocked(settings, dc);
176     }
177 
setWindowingModeLocked(@onNull DisplayContent dc, @WindowConfiguration.WindowingMode int mode)178     void setWindowingModeLocked(@NonNull DisplayContent dc,
179             @WindowConfiguration.WindowingMode int mode) {
180         final DisplayInfo displayInfo = dc.getDisplayInfo();
181         final SettingsProvider.SettingsEntry overrideSettings =
182                 mSettingsProvider.getOverrideSettings(displayInfo);
183         overrideSettings.mWindowingMode = mode;
184         final TaskDisplayArea defaultTda = dc.getDefaultTaskDisplayArea();
185         if (defaultTda != null) {
186             defaultTda.setWindowingMode(mode);
187         }
188         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
189     }
190 
191     @WindowManager.RemoveContentMode
getRemoveContentModeLocked(@onNull DisplayContent dc)192     int getRemoveContentModeLocked(@NonNull DisplayContent dc) {
193         final DisplayInfo displayInfo = dc.getDisplayInfo();
194         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
195         if (settings.mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED) {
196             if (dc.isPrivate() || dc.getDisplay().getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT) {
197                 // For private displays by default content is destroyed on removal.
198                 return REMOVE_CONTENT_MODE_DESTROY;
199             }
200             // For other displays by default content is moved to primary on removal.
201             return REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
202         }
203         return settings.mRemoveContentMode;
204     }
205 
setRemoveContentModeLocked(@onNull DisplayContent dc, @WindowManager.RemoveContentMode int mode)206     void setRemoveContentModeLocked(@NonNull DisplayContent dc,
207             @WindowManager.RemoveContentMode int mode) {
208         final DisplayInfo displayInfo = dc.getDisplayInfo();
209         final SettingsProvider.SettingsEntry overrideSettings =
210                 mSettingsProvider.getOverrideSettings(displayInfo);
211         overrideSettings.mRemoveContentMode = mode;
212         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
213     }
214 
shouldShowWithInsecureKeyguardLocked(@onNull DisplayContent dc)215     boolean shouldShowWithInsecureKeyguardLocked(@NonNull DisplayContent dc) {
216         final DisplayInfo displayInfo = dc.getDisplayInfo();
217         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
218         return settings.mShouldShowWithInsecureKeyguard != null
219                 ? settings.mShouldShowWithInsecureKeyguard : false;
220     }
221 
setShouldShowWithInsecureKeyguardLocked(@onNull DisplayContent dc, boolean shouldShow)222     void setShouldShowWithInsecureKeyguardLocked(@NonNull DisplayContent dc, boolean shouldShow) {
223         if (!dc.isPrivate() && shouldShow) {
224             throw new IllegalArgumentException("Public display can't be allowed to show content"
225                     + " when locked");
226         }
227 
228         final DisplayInfo displayInfo = dc.getDisplayInfo();
229         final SettingsProvider.SettingsEntry overrideSettings =
230                 mSettingsProvider.getOverrideSettings(displayInfo);
231         overrideSettings.mShouldShowWithInsecureKeyguard = shouldShow;
232         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
233     }
234 
setDontMoveToTop(@onNull DisplayContent dc, boolean dontMoveToTop)235     void setDontMoveToTop(@NonNull DisplayContent dc, boolean dontMoveToTop) {
236         DisplayInfo displayInfo = dc.getDisplayInfo();
237         SettingsProvider.SettingsEntry overrideSettings =
238                 mSettingsProvider.getSettings(displayInfo);
239         overrideSettings.mDontMoveToTop = dontMoveToTop;
240         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
241     }
242 
243     /**
244      * Returns {@code true} if either the display is the default display, or the display is allowed
245      * to dynamically add/remove system decorations and the system decorations should be shown on it
246      * currently.
247      */
shouldShowSystemDecorsLocked(@onNull DisplayContent dc)248     boolean shouldShowSystemDecorsLocked(@NonNull DisplayContent dc) {
249         if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
250             // Default display should show system decors.
251             return true;
252         }
253 
254         final DisplayInfo displayInfo = dc.getDisplayInfo();
255         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
256         return settings.mShouldShowSystemDecors != null ? settings.mShouldShowSystemDecors : false;
257     }
258 
setShouldShowSystemDecorsLocked(@onNull DisplayContent dc, boolean shouldShow)259     void setShouldShowSystemDecorsLocked(@NonNull DisplayContent dc, boolean shouldShow) {
260         final boolean changed = (shouldShow != shouldShowSystemDecorsLocked(dc));
261         setShouldShowSystemDecorsInternalLocked(dc, shouldShow);
262 
263         if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) {
264             if (dc.isDefaultDisplay || dc.isPrivate() || !changed) {
265                 return;
266             }
267 
268             dc.getDisplayPolicy().updateHasNavigationBarIfNeeded();
269 
270             if (shouldShow) {
271                 mService.mRoot.startSystemDecorations(dc, "setShouldShowSystemDecorsLocked");
272             } else {
273                 dc.getDisplayPolicy().notifyDisplayRemoveSystemDecorations();
274             }
275         }
276     }
277 
setShouldShowSystemDecorsInternalLocked(@onNull DisplayContent dc, boolean shouldShow)278      void setShouldShowSystemDecorsInternalLocked(@NonNull DisplayContent dc,
279             boolean shouldShow) {
280         final DisplayInfo displayInfo = dc.getDisplayInfo();
281         final SettingsProvider.SettingsEntry overrideSettings =
282                 mSettingsProvider.getOverrideSettings(displayInfo);
283         overrideSettings.mShouldShowSystemDecors = shouldShow;
284         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
285     }
286 
isHomeSupportedLocked(@onNull DisplayContent dc)287     boolean isHomeSupportedLocked(@NonNull DisplayContent dc) {
288         if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
289             // Default display should show home.
290             return true;
291         }
292 
293         final DisplayInfo displayInfo = dc.getDisplayInfo();
294         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
295         return settings.mIsHomeSupported != null
296                 ? settings.mIsHomeSupported
297                 : shouldShowSystemDecorsLocked(dc);
298     }
299 
setHomeSupportedOnDisplayLocked(@onNull String displayUniqueId, int displayType, boolean supported)300     void setHomeSupportedOnDisplayLocked(@NonNull String displayUniqueId, int displayType,
301             boolean supported) {
302         final DisplayInfo displayInfo = new DisplayInfo();
303         displayInfo.uniqueId = displayUniqueId;
304         displayInfo.type = displayType;
305         final SettingsProvider.SettingsEntry overrideSettings =
306                 mSettingsProvider.getOverrideSettings(displayInfo);
307         overrideSettings.mIsHomeSupported = supported;
308         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
309     }
310 
isIgnoreActivitySizeRestrictionsLocked(@onNull DisplayContent dc)311     boolean isIgnoreActivitySizeRestrictionsLocked(@NonNull DisplayContent dc) {
312         final DisplayInfo displayInfo = dc.getDisplayInfo();
313         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
314         return settings.mIgnoreActivitySizeRestrictions != null
315                 && settings.mIgnoreActivitySizeRestrictions;
316     }
317 
setIgnoreActivitySizeRestrictionsOnDisplayLocked(@onNull String displayUniqueId, int displayType, boolean enabled)318     void setIgnoreActivitySizeRestrictionsOnDisplayLocked(@NonNull String displayUniqueId,
319             int displayType, boolean enabled) {
320         final DisplayInfo displayInfo = new DisplayInfo();
321         displayInfo.uniqueId = displayUniqueId;
322         displayInfo.type = displayType;
323         final SettingsProvider.SettingsEntry overrideSettings =
324                 mSettingsProvider.getOverrideSettings(displayInfo);
325         overrideSettings.mIgnoreActivitySizeRestrictions = enabled;
326         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
327     }
328 
clearDisplaySettings(@onNull String displayUniqueId, int displayType)329     void clearDisplaySettings(@NonNull String displayUniqueId, int displayType) {
330         final DisplayInfo displayInfo = new DisplayInfo();
331         displayInfo.uniqueId = displayUniqueId;
332         displayInfo.type = displayType;
333         mSettingsProvider.clearDisplaySettings(displayInfo);
334     }
335 
336     @DisplayImePolicy
getImePolicyLocked(@onNull DisplayContent dc)337     int getImePolicyLocked(@NonNull DisplayContent dc) {
338         if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
339             // Default display should show IME.
340             return DISPLAY_IME_POLICY_LOCAL;
341         }
342 
343         final DisplayInfo displayInfo = dc.getDisplayInfo();
344         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
345         return settings.mImePolicy != null ? settings.mImePolicy
346                 : DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
347     }
348 
setDisplayImePolicy(@onNull DisplayContent dc, @DisplayImePolicy int imePolicy)349     void setDisplayImePolicy(@NonNull DisplayContent dc, @DisplayImePolicy int imePolicy) {
350         final DisplayInfo displayInfo = dc.getDisplayInfo();
351         final SettingsProvider.SettingsEntry overrideSettings =
352                 mSettingsProvider.getOverrideSettings(displayInfo);
353         overrideSettings.mImePolicy = imePolicy;
354         mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
355     }
356 
applySettingsToDisplayLocked(@onNull DisplayContent dc)357     void applySettingsToDisplayLocked(@NonNull DisplayContent dc) {
358         applySettingsToDisplayLocked(dc, /* includeRotationSettings */ true);
359     }
360 
applySettingsToDisplayLocked(@onNull DisplayContent dc, boolean includeRotationSettings)361     void applySettingsToDisplayLocked(@NonNull DisplayContent dc, boolean includeRotationSettings) {
362         final DisplayInfo displayInfo = dc.getDisplayInfo();
363         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
364 
365         // Setting windowing mode first, because it may override overscan values later.
366         final int windowingMode = getWindowingModeLocked(settings, dc);
367         final TaskDisplayArea defaultTda = dc.getDefaultTaskDisplayArea();
368         if (defaultTda != null) {
369             defaultTda.setWindowingMode(windowingMode);
370         }
371         final int userRotationMode = settings.mUserRotationMode != null
372                 ? settings.mUserRotationMode : WindowManagerPolicy.USER_ROTATION_FREE;
373         final int userRotation = settings.mUserRotation != null
374                 ? settings.mUserRotation : Surface.ROTATION_0;
375         final int mFixedToUserRotation = settings.mFixedToUserRotation != null
376                 ? settings.mFixedToUserRotation : IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
377         dc.getDisplayRotation().restoreSettings(userRotationMode, userRotation,
378                 mFixedToUserRotation);
379 
380         final boolean hasDensityOverride = settings.mForcedDensity != 0;
381         final boolean hasDensityOverrideRatio = settings.mForcedDensityRatio != 0.0f;
382         final boolean hasSizeOverride = settings.mForcedWidth != 0 && settings.mForcedHeight != 0;
383         dc.mIsDensityForced = hasDensityOverride;
384         dc.mIsSizeForced = hasSizeOverride;
385 
386         dc.mIgnoreDisplayCutout = settings.mIgnoreDisplayCutout != null
387                 ? settings.mIgnoreDisplayCutout : false;
388 
389         final int width = hasSizeOverride ? settings.mForcedWidth : dc.mInitialDisplayWidth;
390         final int height = hasSizeOverride ? settings.mForcedHeight : dc.mInitialDisplayHeight;
391         final int density = hasDensityOverride ? settings.mForcedDensity
392                 : dc.getInitialDisplayDensity();
393         if (hasDensityOverrideRatio) {
394             dc.mForcedDisplayDensityRatio = settings.mForcedDensityRatio;
395         }
396 
397         dc.updateBaseDisplayMetrics(width, height, density, dc.mBaseDisplayPhysicalXDpi,
398                 dc.mBaseDisplayPhysicalYDpi);
399 
400         final int forcedScalingMode = settings.mForcedScalingMode != null
401                 ? settings.mForcedScalingMode : FORCE_SCALING_MODE_AUTO;
402         dc.mDisplayScalingDisabled = forcedScalingMode == FORCE_SCALING_MODE_DISABLED;
403 
404         boolean dontMoveToTop = settings.mDontMoveToTop != null
405                 ? settings.mDontMoveToTop : false;
406         dc.mDontMoveToTop = !dc.canStealTopFocus() || dontMoveToTop;
407 
408         if (includeRotationSettings) applyRotationSettingsToDisplayLocked(dc);
409     }
410 
applyRotationSettingsToDisplayLocked(@onNull DisplayContent dc)411     void applyRotationSettingsToDisplayLocked(@NonNull DisplayContent dc) {
412         final DisplayInfo displayInfo = dc.getDisplayInfo();
413         final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
414 
415         if (settings.mIgnoreOrientationRequest != null) {
416             dc.setIgnoreOrientationRequest(settings.mIgnoreOrientationRequest);
417         } else if (dc.mHasSetIgnoreOrientationRequest) {
418             // Null entry is default behavior, i.e. do not ignore.
419             dc.setIgnoreOrientationRequest(false);
420         }
421 
422         dc.getDisplayRotation().resetAllowAllRotations();
423     }
424 
425     /**
426      * Updates settings for the given display after system features are loaded into window manager
427      * service, e.g. if this device is PC and if this device supports freeform.
428      *
429      * @param dc the given display.
430      * @return {@code true} if any settings for this display has changed; {@code false} if nothing
431      * changed.
432      */
updateSettingsForDisplay(@onNull DisplayContent dc)433     boolean updateSettingsForDisplay(@NonNull DisplayContent dc) {
434         final TaskDisplayArea defaultTda = dc.getDefaultTaskDisplayArea();
435         if (defaultTda != null && defaultTda.getWindowingMode() != getWindowingModeLocked(dc)) {
436             // For the time being the only thing that may change is windowing mode, so just update
437             // that.
438             defaultTda.setWindowingMode(getWindowingModeLocked(dc));
439             return true;
440         }
441         return false;
442     }
443 
444     /**
445      * Called when the given {@link DisplayContent} is removed to cleanup.
446      */
onDisplayRemoved(@onNull DisplayContent dc)447     void onDisplayRemoved(@NonNull DisplayContent dc) {
448         mSettingsProvider.onDisplayRemoved(dc.getDisplayInfo());
449     }
450 
451     /**
452      * Provides the functionality to lookup the {@link SettingsEntry settings} for a given
453      * {@link DisplayInfo}.
454      * <p>
455      * NOTE: All interactions with implementations of this provider <b>must</b> be thread-safe
456      * externally.
457      */
458     interface SettingsProvider {
459         /**
460          * Returns the {@link SettingsEntry} for a given {@link DisplayInfo}. The values for the
461          * returned settings are guaranteed to match those previously set with
462          * {@link #updateOverrideSettings(DisplayInfo, SettingsEntry)} with all other values left
463          * to the implementation to determine.
464          */
465         @NonNull
getSettings(@onNull DisplayInfo info)466         SettingsEntry getSettings(@NonNull DisplayInfo info);
467 
468         /**
469          * Returns the existing override settings for the given {@link DisplayInfo}. All calls to
470          * {@link #getSettings(DisplayInfo)} for the provided {@code info} are required to have
471          * their values overridden with all set values from the returned {@link SettingsEntry}.
472          *
473          * @see #getSettings(DisplayInfo)
474          * @see #updateOverrideSettings(DisplayInfo, SettingsEntry)
475          */
476         @NonNull
getOverrideSettings(@onNull DisplayInfo info)477         SettingsEntry getOverrideSettings(@NonNull DisplayInfo info);
478 
479         /**
480          * Updates the override settings for a given {@link DisplayInfo}. All subsequent calls to
481          * {@link #getSettings(DisplayInfo)} for the provided {@link DisplayInfo} are required to
482          * have their values match all set values in {@code overrides}.
483          *
484          * @see #getSettings(DisplayInfo)
485          */
updateOverrideSettings(@onNull DisplayInfo info, @NonNull SettingsEntry overrides)486         void updateOverrideSettings(@NonNull DisplayInfo info, @NonNull SettingsEntry overrides);
487 
488         /**
489          * Called when a display is removed to cleanup. Note that for non-virtual displays the
490          * relevant settings entry will be kept, if non-empty.
491          */
onDisplayRemoved(@onNull DisplayInfo info)492         void onDisplayRemoved(@NonNull DisplayInfo info);
493 
494         /**
495          * Explicitly removes all settings entory for the given {@link DisplayInfo}, even if it is
496          * not empty.
497          */
clearDisplaySettings(@onNull DisplayInfo info)498         void clearDisplaySettings(@NonNull DisplayInfo info);
499 
500         /**
501          * Settings for a display.
502          */
503         class SettingsEntry {
504             @WindowConfiguration.WindowingMode
505             int mWindowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
506             @Nullable
507             @WindowManagerPolicy.UserRotationMode
508             Integer mUserRotationMode;
509             @Nullable
510             @Surface.Rotation
511             Integer mUserRotation;
512             int mForcedWidth;
513             int mForcedHeight;
514             int mForcedDensity;
515             /**
516              * The ratio of the forced density to the initial density of the display. This is only
517              * saved for external displays, and used to make sure ratio between forced density and
518              * initial density persist when a resolution change happens. Ratio is updated when
519              * mForcedDensity is changed.
520              */
521             float mForcedDensityRatio;
522             @Nullable
523             @ForceScalingMode
524             Integer mForcedScalingMode;
525             @WindowManager.RemoveContentMode
526             int mRemoveContentMode = REMOVE_CONTENT_MODE_UNDEFINED;
527             @Nullable
528             Boolean mShouldShowWithInsecureKeyguard;
529             @Nullable
530             Boolean mShouldShowSystemDecors;
531             @Nullable
532             Boolean mIsHomeSupported;
533             @Nullable
534             Integer mImePolicy;
535             @Nullable
536             Integer mFixedToUserRotation;
537             @Nullable
538             Boolean mIgnoreOrientationRequest;
539             @Nullable
540             Boolean mIgnoreDisplayCutout;
541             @Nullable
542             Boolean mDontMoveToTop;
543             @Nullable
544             Boolean mIgnoreActivitySizeRestrictions;
545 
SettingsEntry()546             SettingsEntry() {}
547 
SettingsEntry(@onNull SettingsEntry copyFrom)548             SettingsEntry(@NonNull SettingsEntry copyFrom) {
549                 setTo(copyFrom);
550             }
551 
552             /**
553              * Copies all fields from {@code delta} into this {@link SettingsEntry} object, keeping
554              * track of whether a change has occurred.
555              *
556              * @return {@code true} if this settings have changed as a result of the copy,
557              *         {@code false} otherwise.
558              *
559              * @see #updateFrom(SettingsEntry)
560              */
setTo(@onNull SettingsEntry other)561             boolean setTo(@NonNull SettingsEntry other) {
562                 boolean changed = false;
563                 if (other.mWindowingMode != mWindowingMode) {
564                     mWindowingMode = other.mWindowingMode;
565                     changed = true;
566                 }
567                 if (!Objects.equals(other.mUserRotationMode, mUserRotationMode)) {
568                     mUserRotationMode = other.mUserRotationMode;
569                     changed = true;
570                 }
571                 if (!Objects.equals(other.mUserRotation, mUserRotation)) {
572                     mUserRotation = other.mUserRotation;
573                     changed = true;
574                 }
575                 if (other.mForcedWidth != mForcedWidth) {
576                     mForcedWidth = other.mForcedWidth;
577                     changed = true;
578                 }
579                 if (other.mForcedHeight != mForcedHeight) {
580                     mForcedHeight = other.mForcedHeight;
581                     changed = true;
582                 }
583                 if (other.mForcedDensity != mForcedDensity) {
584                     mForcedDensity = other.mForcedDensity;
585                     changed = true;
586                 }
587                 if (other.mForcedDensityRatio != mForcedDensityRatio) {
588                     mForcedDensityRatio = other.mForcedDensityRatio;
589                     changed = true;
590                 }
591                 if (!Objects.equals(other.mForcedScalingMode, mForcedScalingMode)) {
592                     mForcedScalingMode = other.mForcedScalingMode;
593                     changed = true;
594                 }
595                 if (other.mRemoveContentMode != mRemoveContentMode) {
596                     mRemoveContentMode = other.mRemoveContentMode;
597                     changed = true;
598                 }
599                 if (!Objects.equals(
600                         other.mShouldShowWithInsecureKeyguard, mShouldShowWithInsecureKeyguard)) {
601                     mShouldShowWithInsecureKeyguard = other.mShouldShowWithInsecureKeyguard;
602                     changed = true;
603                 }
604                 if (!Objects.equals(other.mShouldShowSystemDecors, mShouldShowSystemDecors)) {
605                     mShouldShowSystemDecors = other.mShouldShowSystemDecors;
606                     changed = true;
607                 }
608                 if (!Objects.equals(other.mIsHomeSupported, mIsHomeSupported)) {
609                     mIsHomeSupported = other.mIsHomeSupported;
610                     changed = true;
611                 }
612                 if (!Objects.equals(other.mImePolicy, mImePolicy)) {
613                     mImePolicy = other.mImePolicy;
614                     changed = true;
615                 }
616                 if (!Objects.equals(other.mFixedToUserRotation, mFixedToUserRotation)) {
617                     mFixedToUserRotation = other.mFixedToUserRotation;
618                     changed = true;
619                 }
620                 if (!Objects.equals(other.mIgnoreOrientationRequest, mIgnoreOrientationRequest)) {
621                     mIgnoreOrientationRequest = other.mIgnoreOrientationRequest;
622                     changed = true;
623                 }
624                 if (!Objects.equals(other.mIgnoreDisplayCutout, mIgnoreDisplayCutout)) {
625                     mIgnoreDisplayCutout = other.mIgnoreDisplayCutout;
626                     changed = true;
627                 }
628                 if (!Objects.equals(other.mDontMoveToTop, mDontMoveToTop)) {
629                     mDontMoveToTop = other.mDontMoveToTop;
630                     changed = true;
631                 }
632                 if (!Objects.equals(other.mIgnoreActivitySizeRestrictions,
633                         mIgnoreActivitySizeRestrictions)) {
634                     mIgnoreActivitySizeRestrictions = other.mIgnoreActivitySizeRestrictions;
635                     changed = true;
636                 }
637                 return changed;
638             }
639 
640             /**
641              * Copies the fields from {@code delta} into this {@link SettingsEntry} object, keeping
642              * track of whether a change has occurred. Any undefined fields in {@code delta} are
643              * ignored and not copied into the current {@link SettingsEntry}.
644              *
645              * @return {@code true} if this settings have changed as a result of the copy,
646              *         {@code false} otherwise.
647              *
648              * @see #setTo(SettingsEntry)
649              */
updateFrom(@onNull SettingsEntry delta)650             boolean updateFrom(@NonNull SettingsEntry delta) {
651                 boolean changed = false;
652                 if (delta.mWindowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED
653                         && delta.mWindowingMode != mWindowingMode) {
654                     mWindowingMode = delta.mWindowingMode;
655                     changed = true;
656                 }
657                 if (delta.mUserRotationMode != null
658                         && !Objects.equals(delta.mUserRotationMode, mUserRotationMode)) {
659                     mUserRotationMode = delta.mUserRotationMode;
660                     changed = true;
661                 }
662                 if (delta.mUserRotation != null
663                         && !Objects.equals(delta.mUserRotation, mUserRotation)) {
664                     mUserRotation = delta.mUserRotation;
665                     changed = true;
666                 }
667                 if (delta.mForcedWidth != 0 && delta.mForcedWidth != mForcedWidth) {
668                     mForcedWidth = delta.mForcedWidth;
669                     changed = true;
670                 }
671                 if (delta.mForcedHeight != 0 && delta.mForcedHeight != mForcedHeight) {
672                     mForcedHeight = delta.mForcedHeight;
673                     changed = true;
674                 }
675                 if (delta.mForcedDensity != 0 && delta.mForcedDensity != mForcedDensity) {
676                     mForcedDensity = delta.mForcedDensity;
677                     changed = true;
678                 }
679                 if (delta.mForcedDensityRatio != 0
680                         && delta.mForcedDensityRatio != mForcedDensityRatio) {
681                     mForcedDensityRatio = delta.mForcedDensityRatio;
682                     changed = true;
683                 }
684                 if (delta.mForcedScalingMode != null
685                         && !Objects.equals(delta.mForcedScalingMode, mForcedScalingMode)) {
686                     mForcedScalingMode = delta.mForcedScalingMode;
687                     changed = true;
688                 }
689                 if (delta.mRemoveContentMode != REMOVE_CONTENT_MODE_UNDEFINED
690                         && delta.mRemoveContentMode != mRemoveContentMode) {
691                     mRemoveContentMode = delta.mRemoveContentMode;
692                     changed = true;
693                 }
694                 if (delta.mShouldShowWithInsecureKeyguard != null && !Objects.equals(
695                         delta.mShouldShowWithInsecureKeyguard, mShouldShowWithInsecureKeyguard)) {
696                     mShouldShowWithInsecureKeyguard = delta.mShouldShowWithInsecureKeyguard;
697                     changed = true;
698                 }
699                 if (delta.mShouldShowSystemDecors != null && !Objects.equals(
700                         delta.mShouldShowSystemDecors, mShouldShowSystemDecors)) {
701                     mShouldShowSystemDecors = delta.mShouldShowSystemDecors;
702                     changed = true;
703                 }
704                 if (delta.mIsHomeSupported != null && !Objects.equals(
705                         delta.mIsHomeSupported, mIsHomeSupported)) {
706                     mIsHomeSupported = delta.mIsHomeSupported;
707                     changed = true;
708                 }
709                 if (delta.mImePolicy != null
710                         && !Objects.equals(delta.mImePolicy, mImePolicy)) {
711                     mImePolicy = delta.mImePolicy;
712                     changed = true;
713                 }
714                 if (delta.mFixedToUserRotation != null
715                         && !Objects.equals(delta.mFixedToUserRotation, mFixedToUserRotation)) {
716                     mFixedToUserRotation = delta.mFixedToUserRotation;
717                     changed = true;
718                 }
719                 if (delta.mIgnoreOrientationRequest != null && !Objects.equals(
720                         delta.mIgnoreOrientationRequest, mIgnoreOrientationRequest)) {
721                     mIgnoreOrientationRequest = delta.mIgnoreOrientationRequest;
722                     changed = true;
723                 }
724                 if (delta.mIgnoreDisplayCutout != null && !Objects.equals(
725                         delta.mIgnoreDisplayCutout, mIgnoreDisplayCutout)) {
726                     mIgnoreDisplayCutout = delta.mIgnoreDisplayCutout;
727                     changed = true;
728                 }
729                 if (delta.mDontMoveToTop != null && !Objects.equals(
730                         delta.mDontMoveToTop, mDontMoveToTop)) {
731                     mDontMoveToTop = delta.mDontMoveToTop;
732                     changed = true;
733                 }
734                 if (delta.mIgnoreActivitySizeRestrictions != null && !Objects.equals(
735                         delta.mIgnoreActivitySizeRestrictions, mIgnoreActivitySizeRestrictions)) {
736                     mIgnoreActivitySizeRestrictions = delta.mIgnoreActivitySizeRestrictions;
737                     changed = true;
738                 }
739                 return changed;
740             }
741 
742             /** @return {@code true} if all values are unset. */
isEmpty()743             boolean isEmpty() {
744                 return mWindowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED
745                         && mUserRotationMode == null
746                         && mUserRotation == null
747                         && mForcedWidth == 0 && mForcedHeight == 0 && mForcedDensity == 0
748                         && mForcedDensityRatio == 0.0f
749                         && mForcedScalingMode == null
750                         && mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED
751                         && mShouldShowWithInsecureKeyguard == null
752                         && mShouldShowSystemDecors == null
753                         && mIsHomeSupported == null
754                         && mImePolicy == null
755                         && mFixedToUserRotation == null
756                         && mIgnoreOrientationRequest == null
757                         && mIgnoreDisplayCutout == null
758                         && mDontMoveToTop == null
759                         && mIgnoreActivitySizeRestrictions == null;
760             }
761 
762             @Override
equals(@ullable Object o)763             public boolean equals(@Nullable Object o) {
764                 if (this == o) return true;
765                 if (o == null || getClass() != o.getClass()) return false;
766                 SettingsEntry that = (SettingsEntry) o;
767                 return mWindowingMode == that.mWindowingMode
768                         && mForcedWidth == that.mForcedWidth
769                         && mForcedHeight == that.mForcedHeight
770                         && mForcedDensity == that.mForcedDensity
771                         && mRemoveContentMode == that.mRemoveContentMode
772                         && mForcedDensityRatio == that.mForcedDensityRatio
773                         && Objects.equals(mUserRotationMode, that.mUserRotationMode)
774                         && Objects.equals(mUserRotation, that.mUserRotation)
775                         && Objects.equals(mForcedScalingMode, that.mForcedScalingMode)
776                         && Objects.equals(mShouldShowWithInsecureKeyguard,
777                                 that.mShouldShowWithInsecureKeyguard)
778                         && Objects.equals(mShouldShowSystemDecors, that.mShouldShowSystemDecors)
779                         && Objects.equals(mIsHomeSupported, that.mIsHomeSupported)
780                         && Objects.equals(mImePolicy, that.mImePolicy)
781                         && Objects.equals(mFixedToUserRotation, that.mFixedToUserRotation)
782                         && Objects.equals(mIgnoreOrientationRequest, that.mIgnoreOrientationRequest)
783                         && Objects.equals(mIgnoreDisplayCutout, that.mIgnoreDisplayCutout)
784                         && Objects.equals(mDontMoveToTop, that.mDontMoveToTop)
785                         && Objects.equals(mIgnoreActivitySizeRestrictions,
786                                 that.mIgnoreActivitySizeRestrictions);
787             }
788 
789             @Override
hashCode()790             public int hashCode() {
791                 return Objects.hash(mWindowingMode, mUserRotationMode, mUserRotation, mForcedWidth,
792                         mForcedHeight, mForcedDensity, mForcedDensityRatio, mForcedScalingMode,
793                         mRemoveContentMode, mShouldShowWithInsecureKeyguard,
794                         mShouldShowSystemDecors, mIsHomeSupported, mImePolicy, mFixedToUserRotation,
795                         mIgnoreOrientationRequest, mIgnoreDisplayCutout, mDontMoveToTop,
796                         mIgnoreActivitySizeRestrictions);
797             }
798 
799             @Override
toString()800             public String toString() {
801                 return "SettingsEntry{"
802                         + "mWindowingMode=" + mWindowingMode
803                         + ", mUserRotationMode=" + mUserRotationMode
804                         + ", mUserRotation=" + mUserRotation
805                         + ", mForcedWidth=" + mForcedWidth
806                         + ", mForcedHeight=" + mForcedHeight
807                         + ", mForcedDensity=" + mForcedDensity
808                         + ", mForcedDensityRatio=" + mForcedDensityRatio
809                         + ", mForcedScalingMode=" + mForcedScalingMode
810                         + ", mRemoveContentMode=" + mRemoveContentMode
811                         + ", mShouldShowWithInsecureKeyguard=" + mShouldShowWithInsecureKeyguard
812                         + ", mShouldShowSystemDecors=" + mShouldShowSystemDecors
813                         + ", mIsHomeSupported=" + mIsHomeSupported
814                         + ", mShouldShowIme=" + mImePolicy
815                         + ", mFixedToUserRotation=" + mFixedToUserRotation
816                         + ", mIgnoreOrientationRequest=" + mIgnoreOrientationRequest
817                         + ", mIgnoreDisplayCutout=" + mIgnoreDisplayCutout
818                         + ", mDontMoveToTop=" + mDontMoveToTop
819                         + ", mForceAppsUniversalResizable=" + mIgnoreActivitySizeRestrictions
820                         + '}';
821             }
822         }
823     }
824 }
825