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