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