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