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.os.IBinder; 21 import android.view.Surface; 22 import android.view.SurfaceControl; 23 24 import java.io.PrintWriter; 25 26 /** 27 * Represents a physical display device such as the built-in display 28 * an external monitor, or a WiFi display. 29 * <p> 30 * Display devices are guarded by the {@link DisplayManagerService.SyncRoot} lock. 31 * </p> 32 */ 33 abstract class DisplayDevice { 34 private final DisplayAdapter mDisplayAdapter; 35 private final IBinder mDisplayToken; 36 37 // The display device does not manage these properties itself, they are set by 38 // the display manager service. The display device shouldn't really be looking at these. 39 private int mCurrentLayerStack = -1; 40 private int mCurrentOrientation = -1; 41 private Rect mCurrentLayerStackRect; 42 private Rect mCurrentDisplayRect; 43 44 // The display device owns its surface, but it should only set it 45 // within a transaction from performTraversalInTransactionLocked. 46 private Surface mCurrentSurface; 47 48 public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken) { 49 mDisplayAdapter = displayAdapter; 50 mDisplayToken = displayToken; 51 } 52 53 /** 54 * Gets the display adapter that owns the display device. 55 * 56 * @return The display adapter. 57 */ 58 public final DisplayAdapter getAdapterLocked() { 59 return mDisplayAdapter; 60 } 61 62 /** 63 * Gets the Surface Flinger display token for this display. 64 * 65 * @return The display token, or null if the display is not being managed 66 * by Surface Flinger. 67 */ 68 public final IBinder getDisplayTokenLocked() { 69 return mDisplayToken; 70 } 71 72 /** 73 * Gets the name of the display device. 74 * 75 * @return The display device name. 76 */ 77 public final String getNameLocked() { 78 return getDisplayDeviceInfoLocked().name; 79 } 80 81 /** 82 * Gets information about the display device. 83 * 84 * The information returned should not change between calls unless the display 85 * adapter sent a {@link DisplayAdapter#DISPLAY_DEVICE_EVENT_CHANGED} event and 86 * {@link #applyPendingDisplayDeviceInfoChangesLocked()} has been called to apply 87 * the pending changes. 88 * 89 * @return The display device info, which should be treated as immutable by the caller. 90 * The display device should allocate a new display device info object whenever 91 * the data changes. 92 */ 93 public abstract DisplayDeviceInfo getDisplayDeviceInfoLocked(); 94 95 /** 96 * Applies any pending changes to the observable state of the display device 97 * if the display adapter sent a {@link DisplayAdapter#DISPLAY_DEVICE_EVENT_CHANGED} event. 98 */ 99 public void applyPendingDisplayDeviceInfoChangesLocked() { 100 } 101 102 /** 103 * Gives the display device a chance to update its properties while in a transaction. 104 */ 105 public void performTraversalInTransactionLocked() { 106 } 107 108 /** 109 * Blanks the display, if supported. 110 */ 111 public void blankLocked() { 112 } 113 114 /** 115 * Unblanks the display, if supported. 116 */ 117 public void unblankLocked() { 118 } 119 120 /** 121 * Sets the display layer stack while in a transaction. 122 */ 123 public final void setLayerStackInTransactionLocked(int layerStack) { 124 if (mCurrentLayerStack != layerStack) { 125 mCurrentLayerStack = layerStack; 126 SurfaceControl.setDisplayLayerStack(mDisplayToken, layerStack); 127 } 128 } 129 130 /** 131 * Sets the display projection while in a transaction. 132 * 133 * @param orientation defines the display's orientation 134 * @param layerStackRect defines which area of the window manager coordinate 135 * space will be used 136 * @param displayRect defines where on the display will layerStackRect be 137 * mapped to. displayRect is specified post-orientation, that is 138 * it uses the orientation seen by the end-user 139 */ 140 public final void setProjectionInTransactionLocked(int orientation, 141 Rect layerStackRect, Rect displayRect) { 142 if (mCurrentOrientation != orientation 143 || mCurrentLayerStackRect == null 144 || !mCurrentLayerStackRect.equals(layerStackRect) 145 || mCurrentDisplayRect == null 146 || !mCurrentDisplayRect.equals(displayRect)) { 147 mCurrentOrientation = orientation; 148 149 if (mCurrentLayerStackRect == null) { 150 mCurrentLayerStackRect = new Rect(); 151 } 152 mCurrentLayerStackRect.set(layerStackRect); 153 154 if (mCurrentDisplayRect == null) { 155 mCurrentDisplayRect = new Rect(); 156 } 157 mCurrentDisplayRect.set(displayRect); 158 159 SurfaceControl.setDisplayProjection(mDisplayToken, 160 orientation, layerStackRect, displayRect); 161 } 162 } 163 164 /** 165 * Sets the display surface while in a transaction. 166 */ 167 public final void setSurfaceInTransactionLocked(Surface surface) { 168 if (mCurrentSurface != surface) { 169 mCurrentSurface = surface; 170 SurfaceControl.setDisplaySurface(mDisplayToken, surface); 171 } 172 } 173 174 /** 175 * Populates the specified viewport object with orientation, 176 * physical and logical rects based on the display's current projection. 177 */ 178 public final void populateViewportLocked(DisplayViewport viewport) { 179 viewport.orientation = mCurrentOrientation; 180 181 if (mCurrentLayerStackRect != null) { 182 viewport.logicalFrame.set(mCurrentLayerStackRect); 183 } else { 184 viewport.logicalFrame.setEmpty(); 185 } 186 187 if (mCurrentDisplayRect != null) { 188 viewport.physicalFrame.set(mCurrentDisplayRect); 189 } else { 190 viewport.physicalFrame.setEmpty(); 191 } 192 193 boolean isRotated = (mCurrentOrientation == Surface.ROTATION_90 194 || mCurrentOrientation == Surface.ROTATION_270); 195 DisplayDeviceInfo info = getDisplayDeviceInfoLocked(); 196 viewport.deviceWidth = isRotated ? info.height : info.width; 197 viewport.deviceHeight = isRotated ? info.width : info.height; 198 } 199 200 /** 201 * Dumps the local state of the display device. 202 * Does not need to dump the display device info because that is already dumped elsewhere. 203 */ 204 public void dumpLocked(PrintWriter pw) { 205 pw.println("mAdapter=" + mDisplayAdapter.getName()); 206 pw.println("mDisplayToken=" + mDisplayToken); 207 pw.println("mCurrentLayerStack=" + mCurrentLayerStack); 208 pw.println("mCurrentOrientation=" + mCurrentOrientation); 209 pw.println("mCurrentLayerStackRect=" + mCurrentLayerStackRect); 210 pw.println("mCurrentDisplayRect=" + mCurrentDisplayRect); 211 pw.println("mCurrentSurface=" + mCurrentSurface); 212 } 213 } 214