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