| /* | 
 | * Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved. | 
 | * | 
 | * Redistribution and use in source and binary forms, with or without | 
 | * modification, are permitted provided that the following conditions are | 
 | * met: | 
 | *    * Redistributions of source code must retain the above copyright | 
 | *      notice, this list of conditions and the following disclaimer. | 
 | *    * Redistributions in binary form must reproduce the above | 
 | *      copyright notice, this list of conditions and the following | 
 | *      disclaimer in the documentation and/or other materials provided | 
 | *      with the distribution. | 
 | *    * Neither the name of The Linux Foundation. nor the names of its | 
 | *      contributors may be used to endorse or promote products derived | 
 | *      from this software without specific prior written permission. | 
 | * | 
 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | 
 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 
 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | 
 | * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | 
 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 
 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 
 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | 
 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 
 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | 
 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | 
 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 | */ | 
 |  | 
 | #include <fcntl.h> | 
 | #include <stdio.h> | 
 | #include <sys/types.h> | 
 | #include <sys/stat.h> | 
 | #include <unistd.h> | 
 | #include <display_config.h> | 
 | #include <QServiceUtils.h> | 
 | #include <qd_utils.h> | 
 |  | 
 | using namespace android; | 
 | using namespace qService; | 
 |  | 
 | namespace qdutils { | 
 |  | 
 | //============================================================================= | 
 | // The functions below run in the client process and wherever necessary | 
 | // do a binder call to HWC to get/set data. | 
 |  | 
 | int isExternalConnected(void) { | 
 |     int ret; | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |     if(binder != NULL) { | 
 |         err = binder->dispatch(IQService::CHECK_EXTERNAL_STATUS, | 
 |                 &inParcel , &outParcel); | 
 |     } | 
 |     if(err) { | 
 |         ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err); | 
 |         ret = err; | 
 |     } else { | 
 |         ret = outParcel.readInt32(); | 
 |     } | 
 |     return ret; | 
 | } | 
 |  | 
 | int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |     inParcel.writeInt32(dpy); | 
 |     if(binder != NULL) { | 
 |         err = binder->dispatch(IQService::GET_DISPLAY_ATTRIBUTES, | 
 |                 &inParcel, &outParcel); | 
 |     } | 
 |     if(!err) { | 
 |         dpyattr.vsync_period = outParcel.readInt32(); | 
 |         dpyattr.xres = outParcel.readInt32(); | 
 |         dpyattr.yres = outParcel.readInt32(); | 
 |         dpyattr.xdpi = outParcel.readFloat(); | 
 |         dpyattr.ydpi = outParcel.readFloat(); | 
 |         dpyattr.panel_type = outParcel.readInt32(); | 
 |     } else { | 
 |         ALOGE("%s() failed with err %d", __FUNCTION__, err); | 
 |     } | 
 |     return err; | 
 | } | 
 |  | 
 | int setHSIC(int dpy, const HSICData_t& hsic_data) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |     inParcel.writeInt32(dpy); | 
 |     inParcel.writeInt32(hsic_data.hue); | 
 |     inParcel.writeFloat(hsic_data.saturation); | 
 |     inParcel.writeInt32(hsic_data.intensity); | 
 |     inParcel.writeFloat(hsic_data.contrast); | 
 |     if(binder != NULL) { | 
 |         err = binder->dispatch(IQService::SET_HSIC_DATA, &inParcel, &outParcel); | 
 |     } | 
 |     if(err) | 
 |         ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err); | 
 |     return err; | 
 | } | 
 |  | 
 | int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |     inParcel.writeInt32(dpy); | 
 |     if(binder != NULL) { | 
 |         err = binder->dispatch(IQService::GET_DISPLAY_VISIBLE_REGION, | 
 |                 &inParcel, &outParcel); | 
 |     } | 
 |     if(!err) { | 
 |         rect.left = outParcel.readInt32(); | 
 |         rect.top = outParcel.readInt32(); | 
 |         rect.right = outParcel.readInt32(); | 
 |         rect.bottom = outParcel.readInt32(); | 
 |     } else { | 
 |         ALOGE("%s: Failed to getVisibleRegion for dpy =%d: err = %d", | 
 |               __FUNCTION__, dpy, err); | 
 |     } | 
 |     return err; | 
 | } | 
 |  | 
 | int setViewFrame(int dpy, int l, int t, int r, int b) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |     inParcel.writeInt32(dpy); | 
 |     inParcel.writeInt32(l); | 
 |     inParcel.writeInt32(t); | 
 |     inParcel.writeInt32(r); | 
 |     inParcel.writeInt32(b); | 
 |  | 
 |     if(binder != NULL) { | 
 |         err = binder->dispatch(IQService::SET_VIEW_FRAME, | 
 |                 &inParcel, &outParcel); | 
 |     } | 
 |     if(err) | 
 |         ALOGE("%s: Failed to set view frame for dpy %d err=%d", | 
 |                             __FUNCTION__, dpy, err); | 
 |  | 
 |     return err; | 
 | } | 
 |  | 
 | int setSecondaryDisplayStatus(int dpy, uint32_t status) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |     inParcel.writeInt32(dpy); | 
 |     inParcel.writeInt32(status); | 
 |  | 
 |     if(binder != NULL) { | 
 |         err = binder->dispatch(IQService::SET_SECONDARY_DISPLAY_STATUS, | 
 |                 &inParcel, &outParcel); | 
 |     } | 
 |     if(err) | 
 |         ALOGE("%s: Failed for dpy %d status = %d err=%d", __FUNCTION__, dpy, | 
 |                                                         status, err); | 
 |  | 
 |     return err; | 
 | } | 
 |  | 
 | int configureDynRefreshRate(uint32_t op, uint32_t refreshRate) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |     inParcel.writeInt32(op); | 
 |     inParcel.writeInt32(refreshRate); | 
 |  | 
 |     if(binder != NULL) { | 
 |         err = binder->dispatch(IQService::CONFIGURE_DYN_REFRESH_RATE, | 
 |                                &inParcel, &outParcel); | 
 |     } | 
 |  | 
 |     if(err) | 
 |         ALOGE("%s: Failed setting op %d err=%d", __FUNCTION__, op, err); | 
 |  | 
 |     return err; | 
 | } | 
 |  | 
 | int getConfigCount(int /*dpy*/) { | 
 |     int numConfigs = -1; | 
 |     sp<IQService> binder = getBinder(); | 
 |     if(binder != NULL) { | 
 |         Parcel inParcel, outParcel; | 
 |         inParcel.writeInt32(DISPLAY_PRIMARY); | 
 |         status_t err = binder->dispatch(IQService::GET_CONFIG_COUNT, | 
 |                 &inParcel, &outParcel); | 
 |         if(!err) { | 
 |             numConfigs = outParcel.readInt32(); | 
 |             ALOGI("%s() Received num configs %d", __FUNCTION__, numConfigs); | 
 |         } else { | 
 |             ALOGE("%s() failed with err %d", __FUNCTION__, err); | 
 |         } | 
 |     } | 
 |     return numConfigs; | 
 | } | 
 |  | 
 | int getActiveConfig(int dpy) { | 
 |     int configIndex = -1; | 
 |     sp<IQService> binder = getBinder(); | 
 |     if(binder != NULL) { | 
 |         Parcel inParcel, outParcel; | 
 |         inParcel.writeInt32(dpy); | 
 |         status_t err = binder->dispatch(IQService::GET_ACTIVE_CONFIG, | 
 |                 &inParcel, &outParcel); | 
 |         if(!err) { | 
 |             configIndex = outParcel.readInt32(); | 
 |             ALOGI("%s() Received active config index %d", __FUNCTION__, | 
 |                     configIndex); | 
 |         } else { | 
 |             ALOGE("%s() failed with err %d", __FUNCTION__, err); | 
 |         } | 
 |     } | 
 |     return configIndex; | 
 | } | 
 |  | 
 | int setActiveConfig(int configIndex, int /*dpy*/) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     if(binder != NULL) { | 
 |         Parcel inParcel, outParcel; | 
 |         inParcel.writeInt32(configIndex); | 
 |         inParcel.writeInt32(DISPLAY_PRIMARY); | 
 |         err = binder->dispatch(IQService::SET_ACTIVE_CONFIG, | 
 |                 &inParcel, &outParcel); | 
 |         if(!err) { | 
 |             ALOGI("%s() Successfully set active config index %d", __FUNCTION__, | 
 |                     configIndex); | 
 |         } else { | 
 |             ALOGE("%s() failed with err %d", __FUNCTION__, err); | 
 |         } | 
 |     } | 
 |     return err; | 
 | } | 
 |  | 
 | DisplayAttributes getDisplayAttributes(int configIndex, int dpy) { | 
 |     DisplayAttributes dpyattr = {}; | 
 |     sp<IQService> binder = getBinder(); | 
 |     if(binder != NULL) { | 
 |         Parcel inParcel, outParcel; | 
 |         inParcel.writeInt32(configIndex); | 
 |         inParcel.writeInt32(dpy); | 
 |         status_t err = binder->dispatch( | 
 |                 IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG, &inParcel, | 
 |                 &outParcel); | 
 |         if(!err) { | 
 |             dpyattr.vsync_period = outParcel.readInt32(); | 
 |             dpyattr.xres = outParcel.readInt32(); | 
 |             dpyattr.yres = outParcel.readInt32(); | 
 |             dpyattr.xdpi = outParcel.readFloat(); | 
 |             dpyattr.ydpi = outParcel.readFloat(); | 
 |             dpyattr.panel_type = outParcel.readInt32(); | 
 |             dpyattr.is_yuv = outParcel.readInt32(); | 
 |             ALOGI("%s() Received attrs for index %d: xres %d, yres %d", | 
 |                     __FUNCTION__, configIndex, dpyattr.xres, dpyattr.yres); | 
 |         } else { | 
 |             ALOGE("%s() failed with err %d", __FUNCTION__, err); | 
 |         } | 
 |     } | 
 |     return dpyattr; | 
 | } | 
 |  | 
 | int setPanelMode(int mode) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     if(binder != NULL) { | 
 |         Parcel inParcel, outParcel; | 
 |         inParcel.writeInt32(mode); | 
 |         err = binder->dispatch(IQService::SET_DISPLAY_MODE, | 
 |                                &inParcel, &outParcel); | 
 |         if(!err) { | 
 |             ALOGI("%s() Successfully set the display mode to %d", __FUNCTION__, | 
 |                   mode); | 
 |         } else { | 
 |             ALOGE("%s() failed with err %d", __FUNCTION__, err); | 
 |         } | 
 |     } | 
 |     return err; | 
 | } | 
 |  | 
 | int setPanelBrightness(int level) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |  | 
 |     if(binder != NULL) { | 
 |         inParcel.writeInt32(level); | 
 |         status_t err = binder->dispatch(IQService::SET_PANEL_BRIGHTNESS, | 
 |                 &inParcel, &outParcel); | 
 |         if(err) { | 
 |             ALOGE("%s() failed with err %d", __FUNCTION__, err); | 
 |         } | 
 |     } | 
 |     return err; | 
 | } | 
 |  | 
 | int getPanelBrightness() { | 
 |     int panel_brightness = -1; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |  | 
 |     if(binder != NULL) { | 
 |         status_t err = binder->dispatch(IQService::GET_PANEL_BRIGHTNESS, | 
 |                 &inParcel, &outParcel); | 
 |         if(!err) { | 
 |             panel_brightness = outParcel.readInt32(); | 
 |             ALOGI("%s() Current panel brightness value %d", __FUNCTION__, | 
 |                     panel_brightness); | 
 |         } else { | 
 |             ALOGE("%s() failed with err %d", __FUNCTION__, err); | 
 |         } | 
 |     } | 
 |     return panel_brightness; | 
 | } | 
 |  | 
 | }// namespace | 
 |  | 
 | // ---------------------------------------------------------------------------- | 
 | // Functions for linking dynamically to libqdutils | 
 | // ---------------------------------------------------------------------------- | 
 | extern "C" int minHdcpEncryptionLevelChanged(int dpy, int min_enc_level) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     Parcel inParcel, outParcel; | 
 |     inParcel.writeInt32(dpy); | 
 |     inParcel.writeInt32(min_enc_level); | 
 |  | 
 |     if(binder != NULL) { | 
 |         err = binder->dispatch(IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED, | 
 |                 &inParcel, &outParcel); | 
 |     } | 
 |  | 
 |     if(err) { | 
 |         ALOGE("%s: Failed for dpy %d err=%d", __FUNCTION__, dpy, err); | 
 |     } else { | 
 |         err = outParcel.readInt32(); | 
 |     } | 
 |  | 
 |     return err; | 
 | } | 
 |  | 
 | extern "C" int refreshScreen() { | 
 |     int ret = 0; | 
 |     ret = screenRefresh(); | 
 |     return ret; | 
 | } | 
 |  | 
 | extern "C" int controlPartialUpdate(int dpy, int mode) { | 
 |     status_t err = (status_t) FAILED_TRANSACTION; | 
 |     sp<IQService> binder = getBinder(); | 
 |     if(binder != NULL) { | 
 |         Parcel inParcel, outParcel; | 
 |         inParcel.writeInt32(dpy); | 
 |         inParcel.writeInt32(mode); | 
 |         err = binder->dispatch(IQService::CONTROL_PARTIAL_UPDATE, &inParcel, &outParcel); | 
 |         if(err != 0) { | 
 |             ALOGE_IF(getBinder(), "%s() failed with err %d", __FUNCTION__, err); | 
 |         } else { | 
 |             return outParcel.readInt32(); | 
 |         } | 
 |     } | 
 |  | 
 |     return err; | 
 | } | 
 |  |