• 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 android.annotation.Nullable;
20 import android.content.Context;
21 import android.graphics.Point;
22 import android.graphics.Rect;
23 import android.hardware.display.DisplayViewport;
24 import android.os.IBinder;
25 import android.util.Slog;
26 import android.view.Display;
27 import android.view.DisplayAddress;
28 import android.view.Surface;
29 import android.view.SurfaceControl;
30 
31 import java.io.PrintWriter;
32 
33 /**
34  * Represents a physical display device such as the built-in display
35  * an external monitor, or a WiFi display.
36  * <p>
37  * Display devices are guarded by the {@link DisplayManagerService.SyncRoot} lock.
38  * </p>
39  */
40 abstract class DisplayDevice {
41     private static final String TAG = "DisplayDevice";
42     private static final Display.Mode EMPTY_DISPLAY_MODE = new Display.Mode.Builder().build();
43 
44     private final DisplayAdapter mDisplayAdapter;
45     private final IBinder mDisplayToken;
46     private final String mUniqueId;
47 
48     protected DisplayDeviceConfig mDisplayDeviceConfig;
49     // The display device does not manage these properties itself, they are set by
50     // the display manager service.  The display device shouldn't really be looking at these.
51     private int mCurrentLayerStack = -1;
52     private int mCurrentFlags = 0;
53     private int mCurrentOrientation = -1;
54     private Rect mCurrentLayerStackRect;
55     private Rect mCurrentDisplayRect;
56     private final Context mContext;
57 
58     // The display device owns its surface, but it should only set it
59     // within a transaction from performTraversalLocked.
60     private Surface mCurrentSurface;
61 
62     // DEBUG STATE: Last device info which was written to the log, or null if none.
63     // Do not use for any other purpose.
64     DisplayDeviceInfo mDebugLastLoggedDeviceInfo;
65 
DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId, Context context)66     public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId,
67             Context context) {
68         mDisplayAdapter = displayAdapter;
69         mDisplayToken = displayToken;
70         mUniqueId = uniqueId;
71         mDisplayDeviceConfig = null;
72         mContext = context;
73     }
74 
75     /**
76      * Gets the display adapter that owns the display device.
77      *
78      * @return The display adapter.
79      */
getAdapterLocked()80     public final DisplayAdapter getAdapterLocked() {
81         return mDisplayAdapter;
82     }
83 
84     /*
85      * Gets the DisplayDeviceConfig for this DisplayDevice.
86      *
87      * @return The DisplayDeviceConfig; {@code null} if not overridden.
88      */
getDisplayDeviceConfig()89     public DisplayDeviceConfig getDisplayDeviceConfig() {
90         if (mDisplayDeviceConfig == null) {
91             mDisplayDeviceConfig = loadDisplayDeviceConfig();
92         }
93         return mDisplayDeviceConfig;
94     }
95 
96     /**
97      * Gets the Surface Flinger display token for this display.
98      *
99      * @return The display token, or null if the display is not being managed
100      * by Surface Flinger.
101      */
getDisplayTokenLocked()102     public final IBinder getDisplayTokenLocked() {
103         return mDisplayToken;
104     }
105 
106     /**
107      * Gets the id of the display to mirror.
108      */
getDisplayIdToMirrorLocked()109     public int getDisplayIdToMirrorLocked() {
110         return Display.DEFAULT_DISPLAY;
111     }
112 
113     /**
114      * Returns the if WindowManager is responsible for mirroring on this display. If {@code false},
115      * then SurfaceFlinger performs no layer mirroring on this display.
116      * Only used for mirroring started from MediaProjection.
117      */
isWindowManagerMirroringLocked()118     public boolean isWindowManagerMirroringLocked() {
119         return false;
120     }
121 
122     /**
123      * Updates if WindowManager is responsible for mirroring on this display. If {@code false}, then
124      * SurfaceFlinger performs no layer mirroring to this display.
125      * Only used for mirroring started from MediaProjection.
126      */
setWindowManagerMirroringLocked(boolean isMirroring)127     public void setWindowManagerMirroringLocked(boolean isMirroring) {
128     }
129 
130     /**
131      * Returns the default size of the surface associated with the display, or null if the surface
132      * is not provided for layer mirroring by SurfaceFlinger.
133      * Only used for mirroring started from MediaProjection.
134      */
135     @Nullable
getDisplaySurfaceDefaultSizeLocked()136     public Point getDisplaySurfaceDefaultSizeLocked() {
137         return null;
138     }
139 
140     /**
141      * Gets the name of the display device.
142      *
143      * @return The display device name.
144      */
getNameLocked()145     public final String getNameLocked() {
146         return getDisplayDeviceInfoLocked().name;
147     }
148 
149     /**
150      * Returns the unique id of the display device.
151      */
getUniqueId()152     public final String getUniqueId() {
153         return mUniqueId;
154     }
155 
156     /**
157      * Returns whether the unique id of the device is stable across reboots.
158      */
hasStableUniqueId()159     public abstract boolean hasStableUniqueId();
160 
161     /**
162      * Gets information about the display device.
163      *
164      * The information returned should not change between calls unless the display
165      * adapter sent a {@link DisplayAdapter#DISPLAY_DEVICE_EVENT_CHANGED} event and
166      * {@link #applyPendingDisplayDeviceInfoChangesLocked()} has been called to apply
167      * the pending changes.
168      *
169      * @return The display device info, which should be treated as immutable by the caller.
170      * The display device should allocate a new display device info object whenever
171      * the data changes.
172      */
getDisplayDeviceInfoLocked()173     public abstract DisplayDeviceInfo getDisplayDeviceInfoLocked();
174 
175     /**
176      * Applies any pending changes to the observable state of the display device
177      * if the display adapter sent a {@link DisplayAdapter#DISPLAY_DEVICE_EVENT_CHANGED} event.
178      */
applyPendingDisplayDeviceInfoChangesLocked()179     public void applyPendingDisplayDeviceInfoChangesLocked() {
180     }
181 
182     /**
183      * Gives the display device a chance to update its properties while in a transaction.
184      */
performTraversalLocked(SurfaceControl.Transaction t)185     public void performTraversalLocked(SurfaceControl.Transaction t) {
186     }
187 
188     /**
189      * Sets the display state, if supported.
190      *
191      * @param state The new display state.
192      * @param brightnessState The new display brightnessState.
193      * @param sdrBrightnessState The new display brightnessState for SDR layers.
194      * @return A runnable containing work to be deferred until after we have
195      * exited the critical section, or null if none.
196      */
requestDisplayStateLocked(int state, float brightnessState, float sdrBrightnessState)197     public Runnable requestDisplayStateLocked(int state, float brightnessState,
198             float sdrBrightnessState) {
199         return null;
200     }
201 
202     /**
203      * Sets the display mode specs.
204      *
205      * Not all display devices will automatically switch between modes, so it's important that the
206      * default modeId is set correctly.
207      */
setDesiredDisplayModeSpecsLocked( DisplayModeDirector.DesiredDisplayModeSpecs displayModeSpecs)208     public void setDesiredDisplayModeSpecsLocked(
209             DisplayModeDirector.DesiredDisplayModeSpecs displayModeSpecs) {}
210 
211     /**
212      * Sets the user preferred display mode. Removes the user preferred display mode and sets
213      * default display mode as the mode chosen by HAL, if 'mode' is null
214      * Returns true if the mode set by user is supported by the display.
215      */
setUserPreferredDisplayModeLocked(Display.Mode mode)216     public void setUserPreferredDisplayModeLocked(Display.Mode mode) { }
217 
218     /**
219      * Returns the user preferred display mode.
220      */
getUserPreferredDisplayModeLocked()221     public Display.Mode getUserPreferredDisplayModeLocked() {
222         return EMPTY_DISPLAY_MODE;
223     }
224 
225     /**
226      * Returns the system preferred display mode.
227      */
getSystemPreferredDisplayModeLocked()228     public Display.Mode getSystemPreferredDisplayModeLocked() {
229         return EMPTY_DISPLAY_MODE;
230     }
231 
232     /**
233      * Returns the display mode that was being used when this display was first found by
234      * display manager.
235      * @hide
236      */
getActiveDisplayModeAtStartLocked()237     public Display.Mode getActiveDisplayModeAtStartLocked() {
238         return EMPTY_DISPLAY_MODE;
239     }
240 
241     /**
242      * Sets the requested color mode.
243      */
setRequestedColorModeLocked(int colorMode)244     public void setRequestedColorModeLocked(int colorMode) {
245     }
246 
247     /**
248      * Sends the Auto Low Latency Mode (ALLM) signal over HDMI, or requests an internal display to
249      * switch to a low-latency mode.
250      *
251      * @param on Whether to set ALLM on or off.
252      */
setAutoLowLatencyModeLocked(boolean on)253     public void setAutoLowLatencyModeLocked(boolean on) {
254     }
255 
256     /**
257      * Sends a ContentType=Game signal over HDMI, or requests an internal display to switch to a
258      * game mode (generally lower latency).
259      *
260      * @param on Whether to send a ContentType=Game signal or not
261      */
setGameContentTypeLocked(boolean on)262     public void setGameContentTypeLocked(boolean on) {
263     }
264 
onOverlayChangedLocked()265     public void onOverlayChangedLocked() {
266     }
267 
268     /**
269      * Sets the display layer stack while in a transaction.
270      */
setLayerStackLocked(SurfaceControl.Transaction t, int layerStack, int layerStackTag)271     public final void setLayerStackLocked(SurfaceControl.Transaction t, int layerStack,
272             int layerStackTag) {
273         if (mCurrentLayerStack != layerStack) {
274             mCurrentLayerStack = layerStack;
275             t.setDisplayLayerStack(mDisplayToken, layerStack);
276             Slog.i(TAG, "[" + layerStackTag + "] Layerstack set to " + layerStack + " for "
277                     + mUniqueId);
278         }
279     }
280 
281     /**
282      * Sets the display flags while in a transaction.
283      *
284      * Valid display flags:
285      *  {@link SurfaceControl#DISPLAY_RECEIVES_INPUT}
286      */
setDisplayFlagsLocked(SurfaceControl.Transaction t, int flags)287     public final void setDisplayFlagsLocked(SurfaceControl.Transaction t, int flags) {
288         if (mCurrentFlags != flags) {
289             mCurrentFlags = flags;
290             t.setDisplayFlags(mDisplayToken, flags);
291         }
292     }
293 
294     /**
295      * Sets the display projection while in a transaction.
296      *
297      * @param orientation defines the display's orientation
298      * @param layerStackRect defines which area of the window manager coordinate
299      *            space will be used
300      * @param displayRect defines where on the display will layerStackRect be
301      *            mapped to. displayRect is specified post-orientation, that is
302      *            it uses the orientation seen by the end-user
303      */
setProjectionLocked(SurfaceControl.Transaction t, int orientation, Rect layerStackRect, Rect displayRect)304     public final void setProjectionLocked(SurfaceControl.Transaction t, int orientation,
305             Rect layerStackRect, Rect displayRect) {
306         if (mCurrentOrientation != orientation
307                 || mCurrentLayerStackRect == null
308                 || !mCurrentLayerStackRect.equals(layerStackRect)
309                 || mCurrentDisplayRect == null
310                 || !mCurrentDisplayRect.equals(displayRect)) {
311             mCurrentOrientation = orientation;
312 
313             if (mCurrentLayerStackRect == null) {
314                 mCurrentLayerStackRect = new Rect();
315             }
316             mCurrentLayerStackRect.set(layerStackRect);
317 
318             if (mCurrentDisplayRect == null) {
319                 mCurrentDisplayRect = new Rect();
320             }
321             mCurrentDisplayRect.set(displayRect);
322 
323             t.setDisplayProjection(mDisplayToken,
324                     orientation, layerStackRect, displayRect);
325         }
326     }
327 
328     /**
329      * Sets the display surface while in a transaction.
330      */
setSurfaceLocked(SurfaceControl.Transaction t, Surface surface)331     public final void setSurfaceLocked(SurfaceControl.Transaction t, Surface surface) {
332         if (mCurrentSurface != surface) {
333             mCurrentSurface = surface;
334             t.setDisplaySurface(mDisplayToken, surface);
335         }
336     }
337 
338     /**
339      * Populates the specified viewport object with orientation,
340      * physical and logical rects based on the display's current projection.
341      */
populateViewportLocked(DisplayViewport viewport)342     public final void populateViewportLocked(DisplayViewport viewport) {
343         viewport.orientation = mCurrentOrientation;
344 
345         if (mCurrentLayerStackRect != null) {
346             viewport.logicalFrame.set(mCurrentLayerStackRect);
347         } else {
348             viewport.logicalFrame.setEmpty();
349         }
350 
351         if (mCurrentDisplayRect != null) {
352             viewport.physicalFrame.set(mCurrentDisplayRect);
353         } else {
354             viewport.physicalFrame.setEmpty();
355         }
356 
357         boolean isRotated = (mCurrentOrientation == Surface.ROTATION_90
358                 || mCurrentOrientation == Surface.ROTATION_270);
359         DisplayDeviceInfo info = getDisplayDeviceInfoLocked();
360         viewport.deviceWidth = isRotated ? info.height : info.width;
361         viewport.deviceHeight = isRotated ? info.width : info.height;
362 
363         viewport.uniqueId = info.uniqueId;
364 
365         if (info.address instanceof DisplayAddress.Physical) {
366             viewport.physicalPort = ((DisplayAddress.Physical) info.address).getPort();
367         } else {
368             viewport.physicalPort = null;
369         }
370     }
371 
372     /**
373      * Dumps the local state of the display device.
374      * Does not need to dump the display device info because that is already dumped elsewhere.
375      */
dumpLocked(PrintWriter pw)376     public void dumpLocked(PrintWriter pw) {
377         pw.println("mAdapter=" + mDisplayAdapter.getName());
378         pw.println("mUniqueId=" + mUniqueId);
379         pw.println("mDisplayToken=" + mDisplayToken);
380         pw.println("mCurrentLayerStack=" + mCurrentLayerStack);
381         pw.println("mCurrentFlags=" + mCurrentFlags);
382         pw.println("mCurrentOrientation=" + mCurrentOrientation);
383         pw.println("mCurrentLayerStackRect=" + mCurrentLayerStackRect);
384         pw.println("mCurrentDisplayRect=" + mCurrentDisplayRect);
385         pw.println("mCurrentSurface=" + mCurrentSurface);
386     }
387 
loadDisplayDeviceConfig()388     private DisplayDeviceConfig loadDisplayDeviceConfig() {
389         return DisplayDeviceConfig.create(mContext, false);
390     }
391 }
392