• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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.display;
18 
19 import static com.android.server.display.DisplayDeviceInfo.TOUCH_NONE;
20 import static com.android.server.display.layout.Layout.Display.POSITION_REAR;
21 import static com.android.server.wm.utils.DisplayInfoOverrides.WM_OVERRIDE_FIELDS;
22 import static com.android.server.wm.utils.DisplayInfoOverrides.copyDisplayInfoFields;
23 
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.graphics.Point;
27 import android.graphics.Rect;
28 import android.hardware.display.DisplayManagerInternal;
29 import android.util.ArraySet;
30 import android.util.SparseArray;
31 import android.view.Display;
32 import android.view.DisplayEventReceiver;
33 import android.view.DisplayInfo;
34 import android.view.Surface;
35 import android.view.SurfaceControl;
36 
37 import com.android.server.display.layout.Layout;
38 import com.android.server.display.mode.DisplayModeDirector;
39 import com.android.server.display.mode.SyntheticModeManager;
40 import com.android.server.wm.utils.InsetUtils;
41 
42 import java.io.PrintWriter;
43 import java.io.StringWriter;
44 import java.util.Arrays;
45 import java.util.Objects;
46 
47 /**
48  * Describes how a logical display is configured.
49  * <p>
50  * At this time, we only support logical displays that are coupled to a particular
51  * primary display device from which the logical display derives its basic properties
52  * such as its size, density and refresh rate.
53  * </p><p>
54  * A logical display may be mirrored onto multiple display devices in addition to its
55  * primary display device.  Note that the contents of a logical display may not
56  * always be visible, even on its primary display device, such as in the case where
57  * the primary display device is currently mirroring content from a different
58  * logical display.
59  * </p><p>
60  * This object is designed to encapsulate as much of the policy of logical
61  * displays as possible.  The idea is to make it easy to implement new kinds of
62  * logical displays mostly by making local changes to this class.
63  * </p><p>
64  * Note: The display manager architecture does not actually require logical displays
65  * to be associated with any individual display device.  Logical displays and
66  * display devices are orthogonal concepts.  Some mapping will exist between
67  * logical displays and display devices but it can be many-to-many and
68  * and some might have no relation at all.
69  * </p><p>
70  * Logical displays are guarded by the {@link DisplayManagerService.SyncRoot} lock.
71  * </p>
72  */
73 final class LogicalDisplay {
74     private static final String TAG = "LogicalDisplay";
75     // The layer stack we use when the display has been blanked to prevent any
76     // of its content from appearing.
77     private static final int BLANK_LAYER_STACK = -1;
78 
79     private static final DisplayInfo EMPTY_DISPLAY_INFO = new DisplayInfo();
80 
81     private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
82     private final int mDisplayId;
83     private final int mLayerStack;
84 
85     // Indicates which display leads this logical display, in terms of brightness or other
86     // properties.
87     // {@link Layout.NO_LEAD_DISPLAY} means that this display is not lead by any others, and could
88     // be a leader itself.
89     private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY;
90 
91     private int mDisplayGroupId = Display.INVALID_DISPLAY_GROUP;
92 
93     /**
94      * Override information set by the window manager. Will be reported instead of {@link #mInfo}
95      * if not null.
96      * @see #setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo)
97      * @see #getDisplayInfoLocked()
98      */
99     private DisplayInfo mOverrideDisplayInfo;
100     /**
101      * Current display info. Initialized with {@link #mBaseDisplayInfo}. Set to {@code null} if
102      * needs to be updated.
103      * @see #getDisplayInfoLocked()
104      */
105     private final DisplayInfoProxy mInfo = new DisplayInfoProxy(null);
106 
107     // The display device that this logical display is based on and which
108     // determines the base metrics that it uses.
109     private DisplayDevice mPrimaryDisplayDevice;
110     private DisplayDeviceInfo mPrimaryDisplayDeviceInfo;
111 
112     // True if the logical display has unique content.
113     private boolean mHasContent;
114 
115     private int mRequestedColorMode;
116     private boolean mRequestedMinimalPostProcessing;
117 
118     private int[] mUserDisabledHdrTypes = {};
119 
120     private DisplayModeDirector.DesiredDisplayModeSpecs mDesiredDisplayModeSpecs =
121             new DisplayModeDirector.DesiredDisplayModeSpecs();
122 
123     // The display offsets to apply to the display projection.
124     private int mDisplayOffsetX;
125     private int mDisplayOffsetY;
126 
127     /**
128      * The position of the display projection sent to SurfaceFlinger
129      */
130     private final Point mDisplayPosition = new Point();
131 
132     /**
133      * {@code true} if display scaling is disabled, or {@code false} if the default scaling mode
134      * is used.
135      * @see #isDisplayScalingDisabled()
136      * @see #setDisplayScalingDisabledLocked(boolean)
137      */
138     private boolean mDisplayScalingDisabled;
139 
140     // Temporary rectangle used when needed.
141     private final Rect mTempLayerStackRect = new Rect();
142     private final Rect mTempDisplayRect = new Rect();
143 
144     /** A session token that controls the offloading operations of this logical display. */
145     private DisplayOffloadSessionImpl mDisplayOffloadSession;
146 
147     /**
148      * Name of a display group to which the display is assigned.
149      */
150     private String mDisplayGroupName;
151 
152     /**
153      * The UID mappings for refresh rate override
154      */
155     private DisplayEventReceiver.FrameRateOverride[] mFrameRateOverrides;
156 
157     /**
158      * Holds a set of UIDs that their frame rate override changed and needs to be notified
159      */
160     private ArraySet<Integer> mPendingFrameRateOverrideUids;
161 
162     /**
163      * Temporary frame rate override list, used when needed.
164      */
165     private final SparseArray<Float> mTempFrameRateOverride;
166 
167     // Indicates the display is enabled (allowed to be ON).
168     private boolean mIsEnabled;
169 
170     // Indicates the display is part of a transition from one device-state ({@link
171     // DeviceStateManager}) to another. Being a "part" of a transition means that either
172     // the {@link mIsEnabled} is changing, or the underlying mPrimaryDisplayDevice is changing.
173     private boolean mIsInTransition;
174 
175     // Indicates the position of the display, POSITION_UNKNOWN could mean it hasn't been specified,
176     // or this is a virtual display etc.
177     private int mDevicePosition = Layout.Display.POSITION_UNKNOWN;
178 
179     // Indicates that something other than the primary display device info has changed and needs to
180     // be handled in the next update.
181     private boolean mDirty = false;
182 
183     /**
184      * The ID of the thermal brightness throttling data that should be used. This can change e.g.
185      * in concurrent displays mode in which a stricter brightness throttling policy might need to
186      * be used.
187      */
188     private String mThermalBrightnessThrottlingDataId;
189 
190     /**
191      * Refresh rate range limitation based on the current device layout
192      */
193     @Nullable
194     private SurfaceControl.RefreshRateRange mLayoutLimitedRefreshRate;
195 
196     /**
197      * The ID of the power throttling data that should be used.
198      */
199     private String mPowerThrottlingDataId;
200 
201     /**
202      * RefreshRateRange limitation for @Temperature.ThrottlingStatus
203      */
204     @NonNull
205     private SparseArray<SurfaceControl.RefreshRateRange> mThermalRefreshRateThrottling =
206             new SparseArray<>();
207 
208     /**
209      * If enabled, will not check for {@link Display#FLAG_ROTATES_WITH_CONTENT} in LogicalDisplay
210      * and simply use the {@link DisplayInfo#rotation} supplied by WindowManager via
211      * {@link #setDisplayInfoOverrideFromWindowManagerLocked}
212      */
213     private boolean mAlwaysRotateDisplayDeviceEnabled;
214 
215     /**
216      * If the aspect ratio of the resolution of the display does not match the physical aspect
217      * ratio of the display, then without this feature enabled, picture would appear stretched to
218      * the user. This is because applications assume that they are rendered on square pixels
219      * (meaning density of pixels in x and y directions are equal). This would result into circles
220      * appearing as ellipses to the user.
221      * To compensate for non-square (anisotropic) pixels, if this feature is enabled:
222      * 1. LogicalDisplay will add more pixels for the applications to render on, as if the pixels
223      * were square and occupied the full display.
224      * 2. SurfaceFlinger will squeeze this taller/wider surface into the available number of
225      * physical pixels in the current display resolution.
226      * 3. If a setting on the display itself is set to "fill the entire display panel" then the
227      * display will stretch the pixels to fill the display fully.
228      */
229     private final boolean mIsAnisotropyCorrectionEnabled;
230 
231     private final boolean mSyncedResolutionSwitchEnabled;
232 
233     private boolean mCanHostTasks;
234 
LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice)235     LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
236         this(displayId, layerStack, primaryDisplayDevice, false, false, false);
237     }
238 
LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice, boolean isAnisotropyCorrectionEnabled, boolean isAlwaysRotateDisplayDeviceEnabled, boolean isSyncedResolutionSwitchEnabled)239     LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice,
240             boolean isAnisotropyCorrectionEnabled, boolean isAlwaysRotateDisplayDeviceEnabled,
241             boolean isSyncedResolutionSwitchEnabled) {
242         mDisplayId = displayId;
243         mLayerStack = layerStack;
244         mPrimaryDisplayDevice = primaryDisplayDevice;
245         mPendingFrameRateOverrideUids = new ArraySet<>();
246         mTempFrameRateOverride = new SparseArray<>();
247         mIsEnabled = true;
248         mIsInTransition = false;
249         mThermalBrightnessThrottlingDataId = DisplayDeviceConfig.DEFAULT_ID;
250         mPowerThrottlingDataId = DisplayDeviceConfig.DEFAULT_ID;
251         mBaseDisplayInfo.thermalBrightnessThrottlingDataId = mThermalBrightnessThrottlingDataId;
252         mIsAnisotropyCorrectionEnabled = isAnisotropyCorrectionEnabled;
253         mAlwaysRotateDisplayDeviceEnabled = isAlwaysRotateDisplayDeviceEnabled;
254         mSyncedResolutionSwitchEnabled = isSyncedResolutionSwitchEnabled;
255         mCanHostTasks = (mDisplayId == Display.DEFAULT_DISPLAY);
256     }
257 
setDevicePositionLocked(int position)258     public void setDevicePositionLocked(int position) {
259         if (mDevicePosition != position) {
260             mDevicePosition = position;
261             mDirty = true;
262         }
263     }
getDevicePositionLocked()264     public int getDevicePositionLocked() {
265         return mDevicePosition;
266     }
267 
268     /**
269      * Gets the logical display id of this logical display.
270      *
271      * @return The logical display id.
272      */
getDisplayIdLocked()273     public int getDisplayIdLocked() {
274         return mDisplayId;
275     }
276 
277     /**
278      * Gets the primary display device associated with this logical display.
279      *
280      * @return The primary display device.
281      */
getPrimaryDisplayDeviceLocked()282     public DisplayDevice getPrimaryDisplayDeviceLocked() {
283         return mPrimaryDisplayDevice;
284     }
285 
286     /**
287      * Gets information about the logical display.
288      *
289      * @return The device info, which should be treated as immutable by the caller.
290      * The logical display should allocate a new display info object whenever
291      * the data changes.
292      */
getDisplayInfoLocked()293     public DisplayInfo getDisplayInfoLocked() {
294         if (mInfo.get() == null) {
295             DisplayInfo info = new DisplayInfo();
296             copyDisplayInfoFields(info, mBaseDisplayInfo, mOverrideDisplayInfo,
297                     WM_OVERRIDE_FIELDS);
298             mInfo.set(info);
299         }
300         return mInfo.get();
301     }
302 
303     /**
304      * Returns the frame rate overrides list
305      */
getFrameRateOverrides()306     public DisplayEventReceiver.FrameRateOverride[] getFrameRateOverrides() {
307         return mFrameRateOverrides;
308     }
309 
310     /**
311      * Returns the list of uids that needs to be updated about their frame rate override
312      */
getPendingFrameRateOverrideUids()313     public ArraySet<Integer> getPendingFrameRateOverrideUids() {
314         return mPendingFrameRateOverrideUids;
315     }
316 
317     /**
318      * Clears the list of uids that needs to be updated about their frame rate override
319      */
clearPendingFrameRateOverrideUids()320     public void clearPendingFrameRateOverrideUids() {
321         mPendingFrameRateOverrideUids = new ArraySet<>();
322     }
323 
324     /**
325      * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo)
326      */
getNonOverrideDisplayInfoLocked(DisplayInfo outInfo)327     void getNonOverrideDisplayInfoLocked(DisplayInfo outInfo) {
328         outInfo.copyFrom(mBaseDisplayInfo);
329     }
330 
331     /**
332      * Sets overridden logical display information from the window manager.
333      * This method can be used to adjust application insets, rotation, and other
334      * properties that the window manager takes care of.
335      *
336      * @param info The logical display information, may be null.
337      */
setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info)338     public boolean setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) {
339         if (info != null) {
340             if (mOverrideDisplayInfo == null) {
341                 mOverrideDisplayInfo = new DisplayInfo(info);
342                 mInfo.set(null);
343                 return true;
344             } else if (!mOverrideDisplayInfo.equals(info)) {
345                 mOverrideDisplayInfo.copyFrom(info);
346                 mInfo.set(null);
347                 return true;
348             }
349         } else if (mOverrideDisplayInfo != null) {
350             mOverrideDisplayInfo = null;
351             mInfo.set(null);
352             return true;
353         }
354         return false;
355     }
356 
357     /**
358      * Returns true if the logical display is in a valid state.
359      * This method should be checked after calling {@link #updateLocked} to handle the
360      * case where a logical display should be removed because all of its associated
361      * display devices are gone or if it is otherwise no longer needed.
362      *
363      * @return True if the logical display is still valid.
364      */
isValidLocked()365     public boolean isValidLocked() {
366         return mPrimaryDisplayDevice != null;
367     }
368 
isDirtyLocked()369     boolean isDirtyLocked() {
370         return mDirty;
371     }
372 
373     /**
374      * Updates the {@link DisplayGroup} to which the logical display belongs.
375      *
376      * @param groupId Identifier for the {@link DisplayGroup}.
377      */
updateDisplayGroupIdLocked(int groupId)378     public void updateDisplayGroupIdLocked(int groupId) {
379         if (groupId != mDisplayGroupId) {
380             mDisplayGroupId = groupId;
381             mDirty = true;
382         }
383     }
384 
385     /**
386      * Updates layoutLimitedRefreshRate
387      *
388      * @param layoutLimitedRefreshRate refresh rate limited by layout or null.
389      */
updateLayoutLimitedRefreshRateLocked( @ullable SurfaceControl.RefreshRateRange layoutLimitedRefreshRate)390     public void updateLayoutLimitedRefreshRateLocked(
391             @Nullable SurfaceControl.RefreshRateRange layoutLimitedRefreshRate) {
392         if (!Objects.equals(layoutLimitedRefreshRate, mLayoutLimitedRefreshRate)) {
393             mLayoutLimitedRefreshRate = layoutLimitedRefreshRate;
394             mDirty = true;
395         }
396     }
397     /**
398      * Updates thermalRefreshRateThrottling
399      *
400      * @param refreshRanges new thermalRefreshRateThrottling ranges limited by layout or default
401      */
updateThermalRefreshRateThrottling( @ullable SparseArray<SurfaceControl.RefreshRateRange> refreshRanges)402     public void updateThermalRefreshRateThrottling(
403             @Nullable SparseArray<SurfaceControl.RefreshRateRange> refreshRanges) {
404         if (refreshRanges == null) {
405             refreshRanges = new SparseArray<>();
406         }
407         if (!mThermalRefreshRateThrottling.contentEquals(refreshRanges)) {
408             mThermalRefreshRateThrottling = refreshRanges;
409             mDirty = true;
410         }
411     }
412 
413     /**
414      * Updates the state of the logical display based on the available display devices.
415      * The logical display might become invalid if it is attached to a display device
416      * that no longer exists.
417      *
418      * @param deviceRepo Repository of active {@link DisplayDevice}s.
419      */
updateLocked(DisplayDeviceRepository deviceRepo, SyntheticModeManager syntheticModeManager)420     public void updateLocked(DisplayDeviceRepository deviceRepo,
421             SyntheticModeManager syntheticModeManager) {
422         // Nothing to update if already invalid.
423         if (mPrimaryDisplayDevice == null) {
424             return;
425         }
426 
427         // Check whether logical display has become invalid.
428         if (!deviceRepo.containsLocked(mPrimaryDisplayDevice)) {
429             setPrimaryDisplayDeviceLocked(null);
430             return;
431         }
432 
433         // Bootstrap the logical display using its associated primary physical display.
434         // We might use more elaborate configurations later.  It's possible that the
435         // configuration of several physical displays might be used to determine the
436         // logical display that they are sharing.  (eg. Adjust size for pixel-perfect
437         // mirroring over HDMI.)
438         DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked();
439         DisplayDeviceConfig config = mPrimaryDisplayDevice.getDisplayDeviceConfig();
440         if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo) || mDirty) {
441             mBaseDisplayInfo.layerStack = mLayerStack;
442             mBaseDisplayInfo.flags = 0;
443             // Displays default to moving content to the primary display when removed
444             mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
445             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
446                 mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS;
447             }
448             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) {
449                 mBaseDisplayInfo.flags |= Display.FLAG_SECURE;
450             }
451             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0) {
452                 mBaseDisplayInfo.flags |= Display.FLAG_PRIVATE;
453                 // For private displays by default content is destroyed on removal.
454                 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
455             }
456             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) {
457                 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
458             }
459             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRESENTATION) != 0) {
460                 mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
461             }
462             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROUND) != 0) {
463                 mBaseDisplayInfo.flags |= Display.FLAG_ROUND;
464             }
465             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
466                 mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
467             }
468             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
469                 mBaseDisplayInfo.flags |= Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
470             }
471             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0) {
472                 mBaseDisplayInfo.flags |= Display.FLAG_TRUSTED;
473             }
474             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) {
475                 mBaseDisplayInfo.flags |= Display.FLAG_OWN_DISPLAY_GROUP;
476             }
477             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED) != 0) {
478                 mBaseDisplayInfo.flags |= Display.FLAG_ALWAYS_UNLOCKED;
479             }
480             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
481                 mBaseDisplayInfo.flags |= Display.FLAG_ROTATES_WITH_CONTENT;
482             }
483             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
484                 mBaseDisplayInfo.flags |= Display.FLAG_TOUCH_FEEDBACK_DISABLED;
485             }
486             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) != 0) {
487                 mBaseDisplayInfo.flags |= Display.FLAG_OWN_FOCUS;
488             }
489             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED) != 0) {
490                 mBaseDisplayInfo.flags |= Display.FLAG_STEAL_TOP_FOCUS_DISABLED;
491             }
492             // Rear display should not be allowed to use the content mode switch.
493             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH) != 0
494                     && mDevicePosition != Layout.Display.POSITION_REAR) {
495                 mBaseDisplayInfo.flags |= Display.FLAG_ALLOWS_CONTENT_MODE_SWITCH;
496             }
497             Rect maskingInsets = getMaskingInsets(deviceInfo);
498             int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
499             int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
500 
501             if (mIsAnisotropyCorrectionEnabled && deviceInfo.type == Display.TYPE_EXTERNAL
502                         && deviceInfo.xDpi > 0 && deviceInfo.yDpi > 0) {
503                 if (deviceInfo.xDpi > deviceInfo.yDpi * DisplayDevice.MAX_ANISOTROPY) {
504                     maskedHeight = (int) (maskedHeight * deviceInfo.xDpi / deviceInfo.yDpi + 0.5);
505                 } else if (deviceInfo.xDpi * DisplayDevice.MAX_ANISOTROPY < deviceInfo.yDpi) {
506                     maskedWidth = (int) (maskedWidth * deviceInfo.yDpi / deviceInfo.xDpi + 0.5);
507                 }
508             }
509 
510             mBaseDisplayInfo.type = deviceInfo.type;
511             mBaseDisplayInfo.address = deviceInfo.address;
512             mBaseDisplayInfo.deviceProductInfo = deviceInfo.deviceProductInfo;
513             mBaseDisplayInfo.name = deviceInfo.name;
514             mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId;
515             mBaseDisplayInfo.appWidth = maskedWidth;
516             mBaseDisplayInfo.appHeight = maskedHeight;
517             mBaseDisplayInfo.logicalWidth = maskedWidth;
518             mBaseDisplayInfo.logicalHeight = maskedHeight;
519             mBaseDisplayInfo.rotation = Surface.ROTATION_0;
520             mBaseDisplayInfo.modeId = deviceInfo.modeId;
521             mBaseDisplayInfo.renderFrameRate = deviceInfo.renderFrameRate;
522             mBaseDisplayInfo.hasArrSupport = deviceInfo.hasArrSupport;
523             mBaseDisplayInfo.frameRateCategoryRate = deviceInfo.frameRateCategoryRate;
524             mBaseDisplayInfo.supportedRefreshRates = Arrays.copyOf(
525                     deviceInfo.supportedRefreshRates, deviceInfo.supportedRefreshRates.length);
526             mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
527             mBaseDisplayInfo.userPreferredModeId = deviceInfo.userPreferredModeId;
528             mBaseDisplayInfo.supportedModes = Arrays.copyOf(
529                     deviceInfo.supportedModes, deviceInfo.supportedModes.length);
530             mBaseDisplayInfo.appsSupportedModes = syntheticModeManager.createAppSupportedModes(
531                     config, mBaseDisplayInfo.supportedModes, mBaseDisplayInfo.hasArrSupport
532             );
533             mBaseDisplayInfo.colorMode = deviceInfo.colorMode;
534             mBaseDisplayInfo.supportedColorModes = Arrays.copyOf(
535                     deviceInfo.supportedColorModes,
536                     deviceInfo.supportedColorModes.length);
537             mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities;
538             mBaseDisplayInfo.isForceSdr = deviceInfo.isForceSdr;
539             mBaseDisplayInfo.userDisabledHdrTypes = mUserDisabledHdrTypes;
540             mBaseDisplayInfo.minimalPostProcessingSupported =
541                     deviceInfo.allmSupported || deviceInfo.gameContentTypeSupported;
542             mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
543             mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
544             mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
545             mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
546             mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
547             mBaseDisplayInfo.state = deviceInfo.state;
548             mBaseDisplayInfo.committedState = deviceInfo.committedState;
549             mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth;
550             mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight;
551             mBaseDisplayInfo.largestNominalAppWidth = maskedWidth;
552             mBaseDisplayInfo.largestNominalAppHeight = maskedHeight;
553             mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid;
554             mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName;
555             boolean maskCutout =
556                     (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
557             mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout;
558             mBaseDisplayInfo.displayId = mDisplayId;
559             mBaseDisplayInfo.displayGroupId = mDisplayGroupId;
560             updateFrameRateOverrides(deviceInfo);
561             mBaseDisplayInfo.brightnessMinimum = deviceInfo.brightnessMinimum;
562             mBaseDisplayInfo.brightnessMaximum = deviceInfo.brightnessMaximum;
563             mBaseDisplayInfo.brightnessDefault = deviceInfo.brightnessDefault;
564             mBaseDisplayInfo.brightnessDim = deviceInfo.brightnessDim;
565             mBaseDisplayInfo.hdrSdrRatio = deviceInfo.hdrSdrRatio;
566             mBaseDisplayInfo.roundedCorners = deviceInfo.roundedCorners;
567             mBaseDisplayInfo.installOrientation = deviceInfo.installOrientation;
568             mBaseDisplayInfo.displayShape = deviceInfo.displayShape;
569 
570             if (mDevicePosition == Layout.Display.POSITION_REAR) {
571                 // A rear display is meant to host a specific experience that is essentially
572                 // a presentation to another user or users other than the main user since they
573                 // can't actually see that display. Given that, it's a suitable display for
574                 // presentations but the content should be destroyed rather than moved to a non-rear
575                 // display when the rear display is removed.
576                 mBaseDisplayInfo.flags |= Display.FLAG_REAR;
577                 mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
578                 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
579             }
580 
581             mBaseDisplayInfo.layoutLimitedRefreshRate = mLayoutLimitedRefreshRate;
582             mBaseDisplayInfo.thermalRefreshRateThrottling = mThermalRefreshRateThrottling;
583             mBaseDisplayInfo.thermalBrightnessThrottlingDataId = mThermalBrightnessThrottlingDataId;
584             mBaseDisplayInfo.canHostTasks = mCanHostTasks;
585 
586             mPrimaryDisplayDeviceInfo = deviceInfo;
587             mInfo.set(null);
588             mDirty = false;
589         }
590     }
591 
updateFrameRateOverrides(DisplayDeviceInfo deviceInfo)592     private void updateFrameRateOverrides(DisplayDeviceInfo deviceInfo) {
593         mTempFrameRateOverride.clear();
594         if (mFrameRateOverrides != null) {
595             for (DisplayEventReceiver.FrameRateOverride frameRateOverride
596                     : mFrameRateOverrides) {
597                 mTempFrameRateOverride.put(frameRateOverride.uid,
598                         frameRateOverride.frameRateHz);
599             }
600         }
601         mFrameRateOverrides = deviceInfo.frameRateOverrides;
602         if (mFrameRateOverrides != null) {
603             for (DisplayEventReceiver.FrameRateOverride frameRateOverride
604                     : mFrameRateOverrides) {
605                 float refreshRate = mTempFrameRateOverride.get(frameRateOverride.uid, 0f);
606                 if (refreshRate == 0 || frameRateOverride.frameRateHz != refreshRate) {
607                     mTempFrameRateOverride.put(frameRateOverride.uid,
608                             frameRateOverride.frameRateHz);
609                 } else {
610                     mTempFrameRateOverride.delete(frameRateOverride.uid);
611                 }
612             }
613         }
614         for (int i = 0; i < mTempFrameRateOverride.size(); i++) {
615             mPendingFrameRateOverrideUids.add(mTempFrameRateOverride.keyAt(i));
616         }
617     }
618 
619     /**
620      * Return the insets currently applied to the display.
621      *
622      * Note that the base DisplayInfo already takes these insets into account, so if you want to
623      * find out the <b>true</b> size of the display, you need to add them back to the logical
624      * dimensions.
625      */
getInsets()626     public Rect getInsets() {
627         return getMaskingInsets(mPrimaryDisplayDeviceInfo);
628     }
629 
630     /**
631      * Returns insets in ROTATION_0 for areas that are masked.
632      */
getMaskingInsets(DisplayDeviceInfo deviceInfo)633     private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) {
634         boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
635         if (maskCutout && deviceInfo.displayCutout != null) {
636             // getSafeInsets is fixed at creation time and cannot change
637             return deviceInfo.displayCutout.getSafeInsets();
638         } else {
639             return new Rect();
640         }
641     }
642 
643     /**
644      * Returns the position of the display's projection.
645      *
646      * @return The x, y coordinates of the display. The return object must be treated as immutable.
647      */
getDisplayPosition()648     Point getDisplayPosition() {
649         // Allocate a new object to avoid a data race.
650         return new Point(mDisplayPosition);
651     }
652 
653     /**
654      * Applies the layer stack and transformation to the given display device
655      * so that it shows the contents of this logical display.
656      *
657      * We know that the given display device is only ever showing the contents of
658      * a single logical display, so this method is expected to blow away all of its
659      * transformation properties to make it happen regardless of what the
660      * display device was previously showing.
661      *
662      * The caller must have an open Surface transaction.
663      *
664      * The display device may not be the primary display device, in the case
665      * where the display is being mirrored.
666      *
667      * @param device The display device to modify.
668      * @param isBlanked True if the device is being blanked.
669      */
configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device, boolean isBlanked)670     public void configureDisplayLocked(SurfaceControl.Transaction t,
671             DisplayDevice device,
672             boolean isBlanked) {
673         // Set the layer stack.
674         device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack, mDisplayId);
675         // Also inform whether the device is the same one sent to inputflinger for its layerstack.
676         // Prevent displays that are disabled from receiving input.
677         // TODO(b/188914255): Remove once input can dispatch against device vs layerstack.
678         device.setDisplayFlagsLocked(t,
679                 (isEnabledLocked() && device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE)
680                         ? SurfaceControl.DISPLAY_RECEIVES_INPUT
681                         : 0);
682 
683         // Set the color mode and allowed display mode.
684         if (device == mPrimaryDisplayDevice) {
685             device.setDesiredDisplayModeSpecsLocked(mDesiredDisplayModeSpecs);
686             device.setRequestedColorModeLocked(mRequestedColorMode);
687         } else {
688             // Reset to default for non primary displays
689             device.setDesiredDisplayModeSpecsLocked(
690                     new DisplayModeDirector.DesiredDisplayModeSpecs());
691             device.setRequestedColorModeLocked(0);
692         }
693 
694         device.setAutoLowLatencyModeLocked(mRequestedMinimalPostProcessing);
695         device.setGameContentTypeLocked(mRequestedMinimalPostProcessing);
696 
697         // Only grab the display info now as it may have been changed based on the requests above.
698         final DisplayInfo displayInfo = getDisplayInfoLocked();
699         final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
700 
701         // Set the viewport.
702         // This is the area of the logical display that we intend to show on the
703         // display device.  For now, it is always the full size of the logical display.
704         mTempLayerStackRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
705 
706         // Set the orientation.
707         // The orientation specifies how the physical coordinate system of the display
708         // is rotated when the contents of the logical display are rendered.
709         int orientation = Surface.ROTATION_0;
710 
711         // FLAG_ROTATES_WITH_CONTENT is now handled in DisplayContent. When the flag
712         // mAlwaysRotateDisplayDeviceEnabled is removed, we should also remove this check for
713         // ROTATES_WITH_CONTENT here and always set the orientation.
714         if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0
715                     || mAlwaysRotateDisplayDeviceEnabled) {
716             orientation = displayInfo.rotation;
717         }
718 
719         // Apply the physical rotation of the display device itself.
720         orientation = (orientation + displayDeviceInfo.rotation) % 4;
721 
722         // Set the frame.
723         // The frame specifies the rotated physical coordinates into which the viewport
724         // is mapped.  We need to take care to preserve the aspect ratio of the viewport.
725         // Currently we maximize the area to fill the display, but we could try to be
726         // more clever and match resolutions.
727         boolean rotated = (orientation == Surface.ROTATION_90
728                 || orientation == Surface.ROTATION_270);
729         int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;
730         int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;
731 
732         Rect maskingInsets = getMaskingInsets(displayDeviceInfo);
733         InsetUtils.rotateInsets(maskingInsets, orientation);
734         // Don't consider the masked area as available when calculating the scaling below.
735         physWidth -= maskingInsets.left + maskingInsets.right;
736         physHeight -= maskingInsets.top + maskingInsets.bottom;
737 
738         var displayLogicalWidth = displayInfo.logicalWidth;
739         var displayLogicalHeight = displayInfo.logicalHeight;
740 
741         if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.type == Display.TYPE_EXTERNAL
742                     && displayDeviceInfo.xDpi > 0 && displayDeviceInfo.yDpi > 0) {
743             if (displayDeviceInfo.xDpi > displayDeviceInfo.yDpi * DisplayDevice.MAX_ANISOTROPY) {
744                 var scalingFactor = displayDeviceInfo.yDpi / displayDeviceInfo.xDpi;
745                 if (rotated) {
746                     displayLogicalWidth = (int) ((float) displayLogicalWidth * scalingFactor + 0.5);
747                 } else {
748                     displayLogicalHeight = (int) ((float) displayLogicalHeight * scalingFactor
749                                                           + 0.5);
750                 }
751             } else if (displayDeviceInfo.xDpi * DisplayDevice.MAX_ANISOTROPY
752                                < displayDeviceInfo.yDpi) {
753                 var scalingFactor = displayDeviceInfo.xDpi / displayDeviceInfo.yDpi;
754                 if (rotated) {
755                     displayLogicalHeight = (int) ((float) displayLogicalHeight * scalingFactor
756                                                           + 0.5);
757                 } else {
758                     displayLogicalWidth = (int) ((float) displayLogicalWidth * scalingFactor + 0.5);
759                 }
760             }
761         }
762 
763         // Determine whether the width or height is more constrained to be scaled.
764         //    physWidth / displayInfo.logicalWidth    => letter box
765         // or physHeight / displayInfo.logicalHeight  => pillar box
766         //
767         // We avoid a division (and possible floating point imprecision) here by
768         // multiplying the fractions by the product of their denominators before
769         // comparing them.
770         int displayRectWidth, displayRectHeight;
771         if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0 || mDisplayScalingDisabled) {
772             displayRectWidth = displayLogicalWidth;
773             displayRectHeight = displayLogicalHeight;
774         } else if (physWidth * displayLogicalHeight
775                 < physHeight * displayLogicalWidth) {
776             // Letter box.
777             displayRectWidth = physWidth;
778             displayRectHeight = displayLogicalHeight * physWidth / displayLogicalWidth;
779         } else {
780             // Pillar box.
781             displayRectWidth = displayLogicalWidth * physHeight / displayLogicalHeight;
782             displayRectHeight = physHeight;
783         }
784         int displayRectTop = (physHeight - displayRectHeight) / 2;
785         int displayRectLeft = (physWidth - displayRectWidth) / 2;
786         mTempDisplayRect.set(displayRectLeft, displayRectTop,
787                 displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
788 
789         // Now add back the offset for the masked area.
790         mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top);
791 
792         if (orientation == Surface.ROTATION_0) {
793             mTempDisplayRect.offset(mDisplayOffsetX, mDisplayOffsetY);
794         } else if (orientation == Surface.ROTATION_90) {
795             mTempDisplayRect.offset(mDisplayOffsetY, -mDisplayOffsetX);
796         } else if (orientation == Surface.ROTATION_180) {
797             mTempDisplayRect.offset(-mDisplayOffsetX, -mDisplayOffsetY);
798         } else {  // Surface.ROTATION_270
799             mTempDisplayRect.offset(-mDisplayOffsetY, mDisplayOffsetX);
800         }
801 
802         mDisplayPosition.set(mTempDisplayRect.left, mTempDisplayRect.top);
803 
804         if (mSyncedResolutionSwitchEnabled || displayDeviceInfo.type == Display.TYPE_VIRTUAL) {
805             device.configureDisplaySizeLocked(t);
806         }
807         device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect);
808         device.configureSurfaceLocked(t);
809     }
810 
811     /**
812      * Returns true if the logical display has unique content.
813      * <p>
814      * If the display has unique content then we will try to ensure that it is
815      * visible on at least its primary display device.  Otherwise we will ignore the
816      * logical display and perhaps show mirrored content on the primary display device.
817      * </p>
818      *
819      * @return True if the display has unique content.
820      */
hasContentLocked()821     public boolean hasContentLocked() {
822         return mHasContent;
823     }
824 
825     /**
826      * Sets whether the logical display has unique content.
827      *
828      * @param hasContent True if the display has unique content.
829      */
setHasContentLocked(boolean hasContent)830     public void setHasContentLocked(boolean hasContent) {
831         mHasContent = hasContent;
832     }
833 
834     /**
835      * Sets the display configs the system can use.
836      */
setDesiredDisplayModeSpecsLocked( DisplayModeDirector.DesiredDisplayModeSpecs specs)837     public void setDesiredDisplayModeSpecsLocked(
838             DisplayModeDirector.DesiredDisplayModeSpecs specs) {
839         mDesiredDisplayModeSpecs = specs;
840     }
841 
842     /**
843      * Returns the display configs the system can choose.
844      */
getDesiredDisplayModeSpecsLocked()845     public DisplayModeDirector.DesiredDisplayModeSpecs getDesiredDisplayModeSpecsLocked() {
846         return mDesiredDisplayModeSpecs;
847     }
848 
849     /**
850      * Requests the given color mode.
851      */
setRequestedColorModeLocked(int colorMode)852     public void setRequestedColorModeLocked(int colorMode) {
853         mRequestedColorMode = colorMode;
854     }
855 
856     /**
857      * Returns the last requested minimal post processing setting.
858      */
getRequestedMinimalPostProcessingLocked()859     public boolean getRequestedMinimalPostProcessingLocked() {
860         return mRequestedMinimalPostProcessing;
861     }
862 
863     /**
864      * Instructs the connected display to do minimal post processing. This is implemented either
865      * via HDMI 2.1 ALLM or HDMI 1.4 ContentType=Game.
866      *
867      * @param on Whether to set minimal post processing on/off on the connected display.
868      */
setRequestedMinimalPostProcessingLocked(boolean on)869     public void setRequestedMinimalPostProcessingLocked(boolean on) {
870         mRequestedMinimalPostProcessing = on;
871     }
872 
873     /** Returns the pending requested color mode. */
getRequestedColorModeLocked()874     public int getRequestedColorModeLocked() {
875         return mRequestedColorMode;
876     }
877 
878     /**
879      * Gets the burn-in offset in X.
880      */
getDisplayOffsetXLocked()881     public int getDisplayOffsetXLocked() {
882         return mDisplayOffsetX;
883     }
884 
885     /**
886      * Gets the burn-in offset in Y.
887      */
getDisplayOffsetYLocked()888     public int getDisplayOffsetYLocked() {
889         return mDisplayOffsetY;
890     }
891 
892     /**
893      * Sets the burn-in offsets.
894      */
setDisplayOffsetsLocked(int x, int y)895     public void setDisplayOffsetsLocked(int x, int y) {
896         mDisplayOffsetX = x;
897         mDisplayOffsetY = y;
898     }
899 
900     /**
901      * @return {@code true} if display scaling is disabled, or {@code false} if the default scaling
902      * mode is used.
903      */
isDisplayScalingDisabled()904     public boolean isDisplayScalingDisabled() {
905         return mDisplayScalingDisabled;
906     }
907 
908     /**
909      * Disables scaling for a display.
910      *
911      * @param disableScaling {@code true} to disable scaling,
912      * {@code false} to use the default scaling behavior of the logical display.
913      */
setDisplayScalingDisabledLocked(boolean disableScaling)914     public void setDisplayScalingDisabledLocked(boolean disableScaling) {
915         mDisplayScalingDisabled = disableScaling;
916     }
917 
setUserDisabledHdrTypes(@onNull int[] userDisabledHdrTypes)918     public void setUserDisabledHdrTypes(@NonNull int[] userDisabledHdrTypes) {
919         if (mUserDisabledHdrTypes != userDisabledHdrTypes) {
920             mUserDisabledHdrTypes = userDisabledHdrTypes;
921             mBaseDisplayInfo.userDisabledHdrTypes = userDisabledHdrTypes;
922             mInfo.set(null);
923         }
924     }
925 
926     /**
927      * Checks whether display is of the type where HDR settings are relevant, and then sets
928      * whether Force SDR conversion mode is active.  isForceSdr is checked by the Display when
929      * returning HDR capabilities.
930      *
931      * @param isForceSdr Whether Force SDR conversion mode is active
932      * @return Whether Display Manager should call handleLogicalDisplayChangedLocked()
933      */
setIsForceSdr(boolean isForceSdr)934     public boolean setIsForceSdr(boolean isForceSdr) {
935         int displayType = getDisplayInfoLocked().type;
936         boolean isTargetDisplayType = displayType == Display.TYPE_INTERNAL
937                 || displayType == Display.TYPE_EXTERNAL
938                 || displayType == Display.TYPE_OVERLAY;
939 
940         boolean handleLogicalDisplayChangedLocked = false;
941         if (isTargetDisplayType && mBaseDisplayInfo.isForceSdr != isForceSdr) {
942             mBaseDisplayInfo.isForceSdr = isForceSdr;
943             mInfo.set(null);
944             handleLogicalDisplayChangedLocked = true;
945         }
946         return handleLogicalDisplayChangedLocked;
947     }
948 
canHostTasksLocked()949     boolean canHostTasksLocked() {
950         return mCanHostTasks;
951     }
952 
953     /**
954      * Sets whether the display can host tasks.
955      *
956      * @param canHostTasks Whether the display can host tasks according to the user's setting.
957      * @return Whether Display Manager should call sendDisplayEventIfEnabledLocked().
958      */
setCanHostTasksLocked(boolean canHostTasks)959     boolean setCanHostTasksLocked(boolean canHostTasks) {
960         canHostTasks = validateCanHostTasksLocked(canHostTasks);
961         if (mBaseDisplayInfo.canHostTasks == canHostTasks) {
962             return false;
963         }
964 
965         mCanHostTasks = canHostTasks;
966         mBaseDisplayInfo.canHostTasks = canHostTasks;
967         mInfo.set(null);
968         return true;
969     }
970 
971     /**
972      * Checks whether the display's ability to host tasks should be determined independently of the
973      * user's setting value. If so, returns the actual validated value based on the display's
974      * usage; otherwise, returns the user's setting value.
975      *
976      * @param canHostTasks Whether the display can host tasks according to the user's setting.
977      * @return Whether the display can actually host task after configuration.
978      */
validateCanHostTasksLocked(boolean canHostTasks)979     private boolean validateCanHostTasksLocked(boolean canHostTasks) {
980         // The default display can always host tasks.
981         if (getDisplayIdLocked() == Display.DEFAULT_DISPLAY) {
982             return true;
983         }
984 
985         // The display that should only mirror can never host tasks.
986         if (mPrimaryDisplayDevice.shouldOnlyMirror()) {
987             return false;
988         }
989 
990         // The display that has its own content can always host tasks.
991         final boolean isRearDisplay = getDevicePositionLocked() == POSITION_REAR;
992         final boolean ownContent =
993                 ((mPrimaryDisplayDevice.getDisplayDeviceInfoLocked().flags
994                         & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY)
995                         != 0)
996                         || isRearDisplay;
997         if (ownContent) {
998             return true;
999         }
1000 
1001         return canHostTasks;
1002     }
1003 
1004     /**
1005      * Swap the underlying {@link DisplayDevice} with the specified LogicalDisplay.
1006      *
1007      * @param targetDisplay The display with which to swap display-devices.
1008      * @return {@code true} if the displays were swapped, {@code false} otherwise.
1009      */
swapDisplaysLocked(@onNull LogicalDisplay targetDisplay)1010     public void swapDisplaysLocked(@NonNull LogicalDisplay targetDisplay) {
1011         final DisplayDevice oldTargetDevice =
1012                 targetDisplay.setPrimaryDisplayDeviceLocked(mPrimaryDisplayDevice);
1013         setPrimaryDisplayDeviceLocked(oldTargetDevice);
1014     }
1015 
1016     /**
1017      * Sets the primary display device to the specified device.
1018      *
1019      * @param device The new device to set.
1020      * @return The previously set display device.
1021      */
setPrimaryDisplayDeviceLocked(@ullable DisplayDevice device)1022     public DisplayDevice setPrimaryDisplayDeviceLocked(@Nullable DisplayDevice device) {
1023         final DisplayDevice old = mPrimaryDisplayDevice;
1024         mPrimaryDisplayDevice = device;
1025 
1026         // Reset all our display info data
1027         mPrimaryDisplayDeviceInfo = null;
1028         mBaseDisplayInfo.copyFrom(EMPTY_DISPLAY_INFO);
1029         mInfo.set(null);
1030 
1031         return old;
1032     }
1033 
1034     /**
1035      * @return {@code true} if the LogicalDisplay is enabled or {@code false}
1036      * if disabled indicating that the display should be hidden from the rest of the apps and
1037      * framework.
1038      */
isEnabledLocked()1039     public boolean isEnabledLocked() {
1040         return mIsEnabled;
1041     }
1042 
1043     /**
1044      * Sets the display as enabled.
1045      *
1046      * @param enabled True if enabled, false otherwise.
1047      */
setEnabledLocked(boolean enabled)1048     public void setEnabledLocked(boolean enabled) {
1049         if (enabled != mIsEnabled) {
1050             mDirty = true;
1051             mIsEnabled = enabled;
1052         }
1053     }
1054 
1055     /**
1056      * @return {@code true} if the LogicalDisplay is in a transition phase. This is used to indicate
1057      * that we are getting ready to swap the underlying display-device and the display should be
1058      * rendered appropriately to reduce jank.
1059      */
isInTransitionLocked()1060     public boolean isInTransitionLocked() {
1061         return mIsInTransition;
1062     }
1063 
1064     /**
1065      * Sets the transition phase.
1066      * @param isInTransition True if it display is in transition.
1067      */
setIsInTransitionLocked(boolean isInTransition)1068     public void setIsInTransitionLocked(boolean isInTransition) {
1069         mIsInTransition = isInTransition;
1070     }
1071 
1072     /**
1073      * @param brightnessThrottlingDataId The ID of the brightness throttling data that this
1074      *                                  display should use.
1075      */
setThermalBrightnessThrottlingDataIdLocked(String brightnessThrottlingDataId)1076     public void setThermalBrightnessThrottlingDataIdLocked(String brightnessThrottlingDataId) {
1077         if (!Objects.equals(brightnessThrottlingDataId, mThermalBrightnessThrottlingDataId)) {
1078             mThermalBrightnessThrottlingDataId = brightnessThrottlingDataId;
1079             mDirty = true;
1080         }
1081     }
1082 
1083     /**
1084      * @param powerThrottlingDataId The ID of the brightness throttling data that this
1085      *                                  display should use.
1086      */
setPowerThrottlingDataIdLocked(String powerThrottlingDataId)1087     public void setPowerThrottlingDataIdLocked(String powerThrottlingDataId) {
1088         if (!Objects.equals(powerThrottlingDataId, mPowerThrottlingDataId)) {
1089             mPowerThrottlingDataId = powerThrottlingDataId;
1090             mDirty = true;
1091         }
1092     }
1093 
1094     /**
1095      * Returns powerThrottlingDataId which is the ID of the brightness
1096      * throttling data that this display should use.
1097      */
getPowerThrottlingDataIdLocked()1098     public String getPowerThrottlingDataIdLocked() {
1099         return mPowerThrottlingDataId;
1100     }
1101 
1102     /**
1103      * Sets the display of which this display is a follower, regarding brightness or other
1104      * properties. If set to {@link Layout#NO_LEAD_DISPLAY}, this display does not follow any
1105      * others, and has the potential to be a lead display to others.
1106      *
1107      * A display cannot be a leader or follower of itself, and there cannot be cycles.
1108      * A display cannot be both a leader and a follower, ie, there must not be any chains.
1109      *
1110      * @param displayId logical display id
1111      */
setLeadDisplayLocked(int displayId)1112     public void setLeadDisplayLocked(int displayId) {
1113         if (mDisplayId != mLeadDisplayId && mDisplayId != displayId) {
1114             mLeadDisplayId = displayId;
1115         }
1116     }
1117 
getLeadDisplayIdLocked()1118     public int getLeadDisplayIdLocked() {
1119         return mLeadDisplayId;
1120     }
1121 
1122     /**
1123      * Sets the name of display group to which the display is assigned.
1124      */
setDisplayGroupNameLocked(String displayGroupName)1125     public void setDisplayGroupNameLocked(String displayGroupName) {
1126         mDisplayGroupName = displayGroupName;
1127     }
1128 
1129     /**
1130      * Gets the name of display group to which the display is assigned.
1131      */
getDisplayGroupNameLocked()1132     public String getDisplayGroupNameLocked() {
1133         return mDisplayGroupName;
1134     }
1135 
setDisplayOffloadSessionLocked(DisplayOffloadSessionImpl session)1136     public void setDisplayOffloadSessionLocked(DisplayOffloadSessionImpl session) {
1137         mDisplayOffloadSession = session;
1138     }
1139 
getDisplayOffloadSessionLocked()1140     public DisplayOffloadSessionImpl getDisplayOffloadSessionLocked() {
1141         return mDisplayOffloadSession;
1142     }
1143 
dumpLocked(PrintWriter pw)1144     public void dumpLocked(PrintWriter pw) {
1145         pw.println("mDisplayId=" + mDisplayId);
1146         pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null
1147                 ? mPrimaryDisplayDevice.getNameLocked() + "(" + mPrimaryDisplayDevice.getUniqueId()
1148                         + ")" : "null"));
1149         pw.println("mIsEnabled=" + mIsEnabled);
1150         pw.println("mIsInTransition=" + mIsInTransition);
1151         pw.println("mLayerStack=" + mLayerStack);
1152         pw.println("mPosition=" + mDevicePosition);
1153         pw.println("mHasContent=" + mHasContent);
1154         pw.println("mDesiredDisplayModeSpecs={" + mDesiredDisplayModeSpecs + "}");
1155         pw.println("mRequestedColorMode=" + mRequestedColorMode);
1156         pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
1157         pw.println("mDisplayScalingDisabled=" + mDisplayScalingDisabled);
1158         pw.println("mBaseDisplayInfo=" + mBaseDisplayInfo);
1159         pw.println("mOverrideDisplayInfo=" + mOverrideDisplayInfo);
1160         pw.println("mRequestedMinimalPostProcessing=" + mRequestedMinimalPostProcessing);
1161         pw.println("mFrameRateOverrides=" + Arrays.toString(mFrameRateOverrides));
1162         pw.println("mPendingFrameRateOverrideUids=" + mPendingFrameRateOverrideUids);
1163         pw.println("mDisplayGroupId=" + mDisplayGroupId);
1164         pw.println("mDisplayGroupName=" + mDisplayGroupName);
1165         pw.println("mThermalBrightnessThrottlingDataId=" + mThermalBrightnessThrottlingDataId);
1166         pw.println("mLeadDisplayId=" + mLeadDisplayId);
1167         pw.println("mLayoutLimitedRefreshRate=" + mLayoutLimitedRefreshRate);
1168         pw.println("mThermalRefreshRateThrottling=" + mThermalRefreshRateThrottling);
1169         pw.println("mPowerThrottlingDataId=" + mPowerThrottlingDataId);
1170     }
1171 
1172     @Override
toString()1173     public String toString() {
1174         StringWriter sw = new StringWriter();
1175         dumpLocked(new PrintWriter(sw));
1176         return sw.toString();
1177     }
1178 }
1179