DisplayDevice.java revision 037c33eae74bee2774897d969d48947f9abe254f
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     * Sets the display state, if supported.
111     */
112    public void requestDisplayStateLocked(int state) {
113    }
114
115    /**
116     * Sets the display layer stack while in a transaction.
117     */
118    public final void setLayerStackInTransactionLocked(int layerStack) {
119        if (mCurrentLayerStack != layerStack) {
120            mCurrentLayerStack = layerStack;
121            SurfaceControl.setDisplayLayerStack(mDisplayToken, layerStack);
122        }
123    }
124
125    /**
126     * Sets the display projection while in a transaction.
127     *
128     * @param orientation defines the display's orientation
129     * @param layerStackRect defines which area of the window manager coordinate
130     *            space will be used
131     * @param displayRect defines where on the display will layerStackRect be
132     *            mapped to. displayRect is specified post-orientation, that is
133     *            it uses the orientation seen by the end-user
134     */
135    public final void setProjectionInTransactionLocked(int orientation,
136            Rect layerStackRect, Rect displayRect) {
137        if (mCurrentOrientation != orientation
138                || mCurrentLayerStackRect == null
139                || !mCurrentLayerStackRect.equals(layerStackRect)
140                || mCurrentDisplayRect == null
141                || !mCurrentDisplayRect.equals(displayRect)) {
142            mCurrentOrientation = orientation;
143
144            if (mCurrentLayerStackRect == null) {
145                mCurrentLayerStackRect = new Rect();
146            }
147            mCurrentLayerStackRect.set(layerStackRect);
148
149            if (mCurrentDisplayRect == null) {
150                mCurrentDisplayRect = new Rect();
151            }
152            mCurrentDisplayRect.set(displayRect);
153
154            SurfaceControl.setDisplayProjection(mDisplayToken,
155                    orientation, layerStackRect, displayRect);
156        }
157    }
158
159    /**
160     * Sets the display surface while in a transaction.
161     */
162    public final void setSurfaceInTransactionLocked(Surface surface) {
163        if (mCurrentSurface != surface) {
164            mCurrentSurface = surface;
165            SurfaceControl.setDisplaySurface(mDisplayToken, surface);
166        }
167    }
168
169    /**
170     * Populates the specified viewport object with orientation,
171     * physical and logical rects based on the display's current projection.
172     */
173    public final void populateViewportLocked(DisplayViewport viewport) {
174        viewport.orientation = mCurrentOrientation;
175
176        if (mCurrentLayerStackRect != null) {
177            viewport.logicalFrame.set(mCurrentLayerStackRect);
178        } else {
179            viewport.logicalFrame.setEmpty();
180        }
181
182        if (mCurrentDisplayRect != null) {
183            viewport.physicalFrame.set(mCurrentDisplayRect);
184        } else {
185            viewport.physicalFrame.setEmpty();
186        }
187
188        boolean isRotated = (mCurrentOrientation == Surface.ROTATION_90
189                || mCurrentOrientation == Surface.ROTATION_270);
190        DisplayDeviceInfo info = getDisplayDeviceInfoLocked();
191        viewport.deviceWidth = isRotated ? info.height : info.width;
192        viewport.deviceHeight = isRotated ? info.width : info.height;
193    }
194
195    /**
196     * Dumps the local state of the display device.
197     * Does not need to dump the display device info because that is already dumped elsewhere.
198     */
199    public void dumpLocked(PrintWriter pw) {
200        pw.println("mAdapter=" + mDisplayAdapter.getName());
201        pw.println("mDisplayToken=" + mDisplayToken);
202        pw.println("mCurrentLayerStack=" + mCurrentLayerStack);
203        pw.println("mCurrentOrientation=" + mCurrentOrientation);
204        pw.println("mCurrentLayerStackRect=" + mCurrentLayerStackRect);
205        pw.println("mCurrentDisplayRect=" + mCurrentDisplayRect);
206        pw.println("mCurrentSurface=" + mCurrentSurface);
207    }
208}
209