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