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