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