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