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