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 
     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