/*
* Copyright (c) 2013-2014, 2016, 2018-2021, 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.
*/

/*
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
 * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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) {
    return FAILED_TRANSACTION;
}

int getDisplayAttributes(int /* dpy */, DisplayAttributes_t& /* dpyattr */) {
    return FAILED_TRANSACTION;
}

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 */) {
    return FAILED_TRANSACTION;
}

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

int setDsiClk(int dpy, uint64_t bitClk) {
    status_t err = (status_t) FAILED_TRANSACTION;
    sp<IQService> binder = getBinder();
    Parcel inParcel, outParcel;

    if(binder != NULL) {
        inParcel.writeInt32(dpy);
        inParcel.writeUint64(bitClk);
        status_t err = binder->dispatch(IQService::SET_DSI_CLK, &inParcel, &outParcel);
        if(err) {
            ALOGE("%s() failed with err %d", __FUNCTION__, err);
        }
    }
    return err;
}

uint64_t getDsiClk(int dpy) {
    uint64_t dsi_clk = 0;
    sp<IQService> binder = getBinder();
    Parcel inParcel, outParcel;

    if(binder != NULL) {
        inParcel.writeInt32(dpy);
        status_t err = binder->dispatch(IQService::GET_DSI_CLK, &inParcel, &outParcel);
        if(!err) {
            dsi_clk = outParcel.readUint64();
        } else {
            ALOGE("%s() failed with err %d", __FUNCTION__, err);
        }
    }
    return dsi_clk;
}

int getSupportedBitClk(int dpy, std::vector<uint64_t>& bit_rates) {
    sp<IQService> binder = getBinder();
    Parcel inParcel, outParcel;

    if(binder != NULL) {
        inParcel.writeInt32(dpy);
        status_t err = binder->dispatch(IQService::GET_SUPPORTED_DSI_CLK, &inParcel, &outParcel);
        if(err) {
            ALOGE("%s() failed with err %d", __FUNCTION__, err);
            return err;
        }
    }

    int32_t clk_levels = outParcel.readInt32();
    while (clk_levels > 0) {
      bit_rates.push_back(outParcel.readUint64());
      clk_levels--;
    }
    return 0;
}

int setPanelLuminanceAttributes(int dpy, float min_lum, float max_lum) {
    status_t err = (status_t) FAILED_TRANSACTION;
    sp<IQService> binder = getBinder();
    Parcel inParcel, outParcel;

    if(binder != NULL) {
        inParcel.writeInt32(dpy);
        inParcel.writeFloat(min_lum);
        inParcel.writeFloat(max_lum);
        status_t err = binder->dispatch(IQService::SET_PANEL_LUMINANCE, &inParcel, &outParcel);
        if(err) {
            ALOGE("%s() failed with err %d", __FUNCTION__, err);
        }
    }
    return err;
}

}// 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 dpy) {
    int ret = 0;
    ret = screenRefresh(dpy);
    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;
}

// returns 0 if composer is up
extern "C" int waitForComposerInit() {
    int status = false;
    sp<IQService> binder = getBinder();
    if (binder == NULL) {
        sleep(2);
        binder = getBinder();
    }

    if (binder != NULL) {
        Parcel inParcel, outParcel;
        binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
        status = !!outParcel.readInt32();
        if (!status) {
            sleep(2);
            binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
            status = !!outParcel.readInt32();
        }
    }

    return !status;
}

extern "C" int setStandByMode(int mode, int is_twm = false) {
    status_t err = (status_t) FAILED_TRANSACTION;
    sp<IQService> binder = getBinder();
    Parcel inParcel, outParcel;

    if(binder != NULL) {
        inParcel.writeInt32(mode);
        inParcel.writeInt32(is_twm);
        err = binder->dispatch(IQService::SET_STAND_BY_MODE,
              &inParcel, &outParcel);
        if(err) {
            ALOGE("%s() failed with err %d", __FUNCTION__, err);
        }
    }
    return err;
}

extern "C" int getPanelResolution(int *width, int *height) {
    status_t err = (status_t) FAILED_TRANSACTION;
    sp<IQService> binder = getBinder();
    Parcel inParcel, outParcel;

    if(binder != NULL) {
        err = binder->dispatch(IQService::GET_PANEL_RESOLUTION,
              &inParcel, &outParcel);
        if(err != 0) {
            ALOGE_IF(getBinder(), "%s() failed with err %d", __FUNCTION__, err);
        } else {
            *width = outParcel.readInt32();
            *height = outParcel.readInt32();
        }
    }

    return err;
}

extern "C" int delayFirstCommit(void) {
    status_t err = (status_t) FAILED_TRANSACTION;
    sp<IQService> binder = getBinder();
    if(binder != NULL) {
        err = binder->dispatch(IQService::DELAY_FIRST_COMMIT, NULL, NULL);
        if(err) {
            ALOGE("%s() failed with err %d", __FUNCTION__, err);
        }
    }
    return err;
}
