Home | History | Annotate | Download | only in libhwcomposer
      1 /*
      2  *  Copyright (c) 2013-14, The Linux Foundation. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *     * Redistributions of source code must retain the above copyright
      8  *       notice, this list of conditions and the following disclaimer.
      9  *     * Redistributions in binary form must reproduce the above
     10  *       copyright notice, this list of conditions and the following
     11  *       disclaimer in the documentation and/or other materials provided
     12  *       with the distribution.
     13  *     * Neither the name of The Linux Foundation nor the names of its
     14  *       contributors may be used to endorse or promote products derived
     15  *       from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR CLIENTS; LOSS OF USE, DATA, OR PROFITS; OR
     24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include <hwc_qclient.h>
     31 #include <IQService.h>
     32 #include <hwc_utils.h>
     33 #include <mdp_version.h>
     34 
     35 #define QCLIENT_DEBUG 0
     36 
     37 using namespace android;
     38 using namespace qService;
     39 using namespace qhwc;
     40 
     41 namespace qClient {
     42 
     43 // ----------------------------------------------------------------------------
     44 QClient::QClient(hwc_context_t *ctx) : mHwcContext(ctx),
     45         mMPDeathNotifier(new MPDeathNotifier(ctx))
     46 {
     47     ALOGD_IF(QCLIENT_DEBUG, "QClient Constructor invoked");
     48 }
     49 
     50 QClient::~QClient()
     51 {
     52     ALOGD_IF(QCLIENT_DEBUG,"QClient Destructor invoked");
     53 }
     54 
     55 static void securing(hwc_context_t *ctx, uint32_t startEnd) {
     56     Locker::Autolock _sl(ctx->mDrawLock);
     57     //The only way to make this class in this process subscribe to media
     58     //player's death.
     59     IMediaDeathNotifier::getMediaPlayerService();
     60 
     61     ctx->mSecuring = startEnd;
     62     //We're done securing
     63     if(startEnd == IQService::END)
     64         ctx->mSecureMode = true;
     65     if(ctx->proc)
     66         ctx->proc->invalidate(ctx->proc);
     67 }
     68 
     69 static void unsecuring(hwc_context_t *ctx, uint32_t startEnd) {
     70     Locker::Autolock _sl(ctx->mDrawLock);
     71     ctx->mSecuring = startEnd;
     72     //We're done unsecuring
     73     if(startEnd == IQService::END)
     74         ctx->mSecureMode = false;
     75     if(ctx->proc)
     76         ctx->proc->invalidate(ctx->proc);
     77 }
     78 
     79 void QClient::MPDeathNotifier::died() {
     80     Locker::Autolock _sl(mHwcContext->mDrawLock);
     81     ALOGD_IF(QCLIENT_DEBUG, "Media Player died");
     82     mHwcContext->mSecuring = false;
     83     mHwcContext->mSecureMode = false;
     84     if(mHwcContext->proc)
     85         mHwcContext->proc->invalidate(mHwcContext->proc);
     86 }
     87 
     88 static android::status_t screenRefresh(hwc_context_t *ctx) {
     89     status_t result = NO_INIT;
     90     if(ctx->proc) {
     91         ctx->proc->invalidate(ctx->proc);
     92         result = NO_ERROR;
     93     }
     94     return result;
     95 }
     96 
     97 static void setExtOrientation(hwc_context_t *ctx, uint32_t orientation) {
     98     ctx->mExtOrientation = orientation;
     99 }
    100 
    101 static void isExternalConnected(hwc_context_t* ctx, Parcel* outParcel) {
    102     int connected;
    103     connected = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected ? 1 : 0;
    104     outParcel->writeInt32(connected);
    105 }
    106 
    107 static void getDisplayAttributes(hwc_context_t* ctx, const Parcel* inParcel,
    108         Parcel* outParcel) {
    109     int dpy = inParcel->readInt32();
    110     outParcel->writeInt32(ctx->dpyAttr[dpy].vsync_period);
    111     outParcel->writeInt32(ctx->dpyAttr[dpy].xres);
    112     outParcel->writeInt32(ctx->dpyAttr[dpy].yres);
    113     outParcel->writeFloat(ctx->dpyAttr[dpy].xdpi);
    114     outParcel->writeFloat(ctx->dpyAttr[dpy].ydpi);
    115     //XXX: Need to check what to return for HDMI
    116     outParcel->writeInt32(ctx->mMDP.panel);
    117 }
    118 static void setHSIC(const Parcel* inParcel) {
    119     int dpy = inParcel->readInt32();
    120     ALOGD_IF(0, "In %s: dpy = %d", __FUNCTION__, dpy);
    121     HSICData_t hsic_data;
    122     hsic_data.hue = inParcel->readInt32();
    123     hsic_data.saturation = inParcel->readFloat();
    124     hsic_data.intensity = inParcel->readInt32();
    125     hsic_data.contrast = inParcel->readFloat();
    126     //XXX: Actually set the HSIC data through ABL lib
    127 }
    128 
    129 
    130 static void setBufferMirrorMode(hwc_context_t *ctx, uint32_t enable) {
    131     ctx->mBufferMirrorMode = enable;
    132 }
    133 
    134 static status_t getDisplayVisibleRegion(hwc_context_t* ctx, int dpy,
    135                                 Parcel* outParcel) {
    136     // Get the info only if the dpy is valid
    137     if(dpy >= HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
    138         Locker::Autolock _sl(ctx->mDrawLock);
    139         if(dpy && (ctx->mExtOrientation || ctx->mBufferMirrorMode)) {
    140             // Return the destRect on external, if external orienation
    141             // is enabled
    142             outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.left);
    143             outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.top);
    144             outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.right);
    145             outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.bottom);
    146         } else {
    147             outParcel->writeInt32(ctx->mViewFrame[dpy].left);
    148             outParcel->writeInt32(ctx->mViewFrame[dpy].top);
    149             outParcel->writeInt32(ctx->mViewFrame[dpy].right);
    150             outParcel->writeInt32(ctx->mViewFrame[dpy].bottom);
    151         }
    152         return NO_ERROR;
    153     } else {
    154         ALOGE("In %s: invalid dpy index %d", __FUNCTION__, dpy);
    155         return BAD_VALUE;
    156     }
    157 }
    158 
    159 static void pauseWFD(hwc_context_t *ctx, uint32_t pause) {
    160     /* TODO: Will remove pauseWFD once all the clients start using
    161      * setWfdStatus to indicate the status of WFD display
    162      */
    163     int dpy = HWC_DISPLAY_VIRTUAL;
    164     if(pause) {
    165         //WFD Pause
    166         handle_pause(ctx, dpy);
    167     } else {
    168         //WFD Resume
    169         handle_resume(ctx, dpy);
    170     }
    171 }
    172 
    173 static void setWfdStatus(hwc_context_t *ctx, uint32_t wfdStatus) {
    174 
    175     ALOGD_IF(HWC_WFDDISPSYNC_LOG,
    176              "%s: Received a binder call that WFD state is %s",
    177              __FUNCTION__,getExternalDisplayState(wfdStatus));
    178     int dpy = HWC_DISPLAY_VIRTUAL;
    179 
    180     if(wfdStatus == EXTERNAL_OFFLINE) {
    181         ctx->mWfdSyncLock.lock();
    182         ctx->mWfdSyncLock.signal();
    183         ctx->mWfdSyncLock.unlock();
    184     } else if(wfdStatus == EXTERNAL_PAUSE) {
    185         handle_pause(ctx, dpy);
    186     } else if(wfdStatus == EXTERNAL_RESUME) {
    187         handle_resume(ctx, dpy);
    188     }
    189 }
    190 
    191 status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
    192         Parcel* outParcel) {
    193     status_t ret = NO_ERROR;
    194 
    195     switch(command) {
    196         case IQService::SECURING:
    197             securing(mHwcContext, inParcel->readInt32());
    198             break;
    199         case IQService::UNSECURING:
    200             unsecuring(mHwcContext, inParcel->readInt32());
    201             break;
    202         case IQService::SCREEN_REFRESH:
    203             return screenRefresh(mHwcContext);
    204             break;
    205         case IQService::EXTERNAL_ORIENTATION:
    206             setExtOrientation(mHwcContext, inParcel->readInt32());
    207             break;
    208         case IQService::BUFFER_MIRRORMODE:
    209             setBufferMirrorMode(mHwcContext, inParcel->readInt32());
    210             break;
    211         case IQService::GET_DISPLAY_VISIBLE_REGION:
    212             ret = getDisplayVisibleRegion(mHwcContext, inParcel->readInt32(),
    213                                     outParcel);
    214             break;
    215         case IQService::CHECK_EXTERNAL_STATUS:
    216             isExternalConnected(mHwcContext, outParcel);
    217             break;
    218         case IQService::GET_DISPLAY_ATTRIBUTES:
    219             getDisplayAttributes(mHwcContext, inParcel, outParcel);
    220             break;
    221         case IQService::SET_HSIC_DATA:
    222             setHSIC(inParcel);
    223             break;
    224         case IQService::PAUSE_WFD:
    225             pauseWFD(mHwcContext, inParcel->readInt32());
    226             break;
    227         case IQService::SET_WFD_STATUS:
    228             setWfdStatus(mHwcContext,inParcel->readInt32());
    229             break;
    230         default:
    231             ret = NO_ERROR;
    232     }
    233     return ret;
    234 }
    235 
    236 }
    237