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