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