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