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