/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "SurfaceFlinger"

#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>

#include <linux/unistd.h>

#include <utils/Log.h>

#include "DisplayHardware/DisplayHardwareBase.h"
#include "SurfaceFlinger.h"

// ----------------------------------------------------------------------------
// the sim build doesn't have gettid

#ifndef HAVE_GETTID
# define gettid getpid
#endif

// ----------------------------------------------------------------------------
namespace android {

static char const * kSleepFileName = "/sys/power/wait_for_fb_sleep";
static char const * kWakeFileName = "/sys/power/wait_for_fb_wake";
static char const * const kOldSleepFileName = "/sys/android_power/wait_for_fb_sleep";
static char const * const kOldWakeFileName = "/sys/android_power/wait_for_fb_wake";

// This dir exists if the framebuffer console is present, either built into
// the kernel or loaded as a module.
static char const * const kFbconSysDir = "/sys/class/graphics/fbcon";

// ----------------------------------------------------------------------------

DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase(
        const sp<SurfaceFlinger>& flinger)
    : Thread(false), mFlinger(flinger) {
}

DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() {
}

// ----------------------------------------------------------------------------

DisplayHardwareBase::DisplayEventThread::DisplayEventThread(
        const sp<SurfaceFlinger>& flinger)
    : DisplayEventThreadBase(flinger)
{
}

DisplayHardwareBase::DisplayEventThread::~DisplayEventThread()
{
}

bool DisplayHardwareBase::DisplayEventThread::threadLoop()
{
    int err = 0;
    char buf;
    int fd;

    fd = open(kSleepFileName, O_RDONLY, 0);
    do {
      err = read(fd, &buf, 1);
    } while (err < 0 && errno == EINTR);
    close(fd);
    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
    if (err >= 0) {
        sp<SurfaceFlinger> flinger = mFlinger.promote();
        LOGD("About to give-up screen, flinger = %p", flinger.get());
        if (flinger != 0) {
            mBarrier.close();
            flinger->screenReleased(0);
            mBarrier.wait();
        }
    }
    fd = open(kWakeFileName, O_RDONLY, 0);
    do {
      err = read(fd, &buf, 1);
    } while (err < 0 && errno == EINTR);
    close(fd);
    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
    if (err >= 0) {
        sp<SurfaceFlinger> flinger = mFlinger.promote();
        LOGD("Screen about to return, flinger = %p", flinger.get());
        if (flinger != 0)
            flinger->screenAcquired(0);
    }
    return true;
}

status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const
{
    mBarrier.open();
    return NO_ERROR;
}

status_t DisplayHardwareBase::DisplayEventThread::readyToRun()
{
    if (access(kSleepFileName, R_OK) || access(kWakeFileName, R_OK)) {
        if (access(kOldSleepFileName, R_OK) || access(kOldWakeFileName, R_OK)) {
            LOGE("Couldn't open %s or %s", kSleepFileName, kWakeFileName);
            return NO_INIT;
        }
        kSleepFileName = kOldSleepFileName;
        kWakeFileName = kOldWakeFileName;
    }
    return NO_ERROR;
}

status_t DisplayHardwareBase::DisplayEventThread::initCheck() const
{
    return (((access(kSleepFileName, R_OK) == 0 &&
            access(kWakeFileName, R_OK) == 0) ||
            (access(kOldSleepFileName, R_OK) == 0 &&
            access(kOldWakeFileName, R_OK) == 0)) &&
            access(kFbconSysDir, F_OK) != 0) ? NO_ERROR : NO_INIT;
}

// ----------------------------------------------------------------------------

pid_t DisplayHardwareBase::ConsoleManagerThread::sSignalCatcherPid = 0;

DisplayHardwareBase::ConsoleManagerThread::ConsoleManagerThread(
        const sp<SurfaceFlinger>& flinger)
    : DisplayEventThreadBase(flinger), consoleFd(-1)
{   
    sSignalCatcherPid = 0;

    // create a new console
    char const * const ttydev = "/dev/tty0";
    int fd = open(ttydev, O_RDWR | O_SYNC);
    if (fd<0) {
        LOGE("Can't open %s", ttydev);
        this->consoleFd = -errno;
        return;
    }

    // to make sure that we are in text mode
    int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
    if (res<0) {
        LOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
                fd, res, strerror(errno));
    }
    
    // get the current console
    struct vt_stat vs;
    res = ioctl(fd, VT_GETSTATE, &vs);
    if (res<0) {
        LOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
                fd, res, strerror(errno));
        this->consoleFd = -errno;
        return;
    }

    // switch to console 7 (which is what X normaly uses)
    int vtnum = 7;
    do {
        res = ioctl(fd, VT_ACTIVATE, (void*)vtnum);
    } while(res < 0 && errno == EINTR);
    if (res<0) {
        LOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for %d",
                fd, errno, strerror(errno), vtnum);
        this->consoleFd = -errno;
        return;
    }

    do {
        res = ioctl(fd, VT_WAITACTIVE, (void*)vtnum);
    } while(res < 0 && errno == EINTR);
    if (res<0) {
        LOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for %d",
                fd, res, errno, strerror(errno), vtnum);
        this->consoleFd = -errno;
        return;
    }

    // open the new console
    close(fd);
    fd = open(ttydev, O_RDWR | O_SYNC);
    if (fd<0) {
        LOGE("Can't open new console %s", ttydev);
        this->consoleFd = -errno;
        return;
    }

    /* disable console line buffer, echo, ... */
    struct termios ttyarg;
    ioctl(fd, TCGETS , &ttyarg);
    ttyarg.c_iflag = 0;
    ttyarg.c_lflag = 0;
    ioctl(fd, TCSETS , &ttyarg);

    // set up signals so we're notified when the console changes
    // we can't use SIGUSR1 because it's used by the java-vm
    vm.mode = VT_PROCESS;
    vm.waitv = 0;
    vm.relsig = SIGUSR2;
    vm.acqsig = SIGUNUSED;
    vm.frsig = 0;

    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_handler = sigHandler;
    act.sa_flags = 0;
    sigaction(vm.relsig, &act, NULL);

    sigemptyset(&act.sa_mask);
    act.sa_handler = sigHandler;
    act.sa_flags = 0;
    sigaction(vm.acqsig, &act, NULL);

    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, vm.relsig);
    sigaddset(&mask, vm.acqsig);
    sigprocmask(SIG_BLOCK, &mask, NULL);

    // switch to graphic mode
    res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
    LOGW_IF(res<0,
            "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);

    this->prev_vt_num = vs.v_active;
    this->vt_num = vtnum;
    this->consoleFd = fd;
}

DisplayHardwareBase::ConsoleManagerThread::~ConsoleManagerThread()
{   
    if (this->consoleFd >= 0) {
        int fd = this->consoleFd;
        int prev_vt_num = this->prev_vt_num;
        int res;
        ioctl(fd, KDSETMODE, (void*)KD_TEXT);
        do {
            res = ioctl(fd, VT_ACTIVATE, (void*)prev_vt_num);
        } while(res < 0 && errno == EINTR);
        do {
            res = ioctl(fd, VT_WAITACTIVE, (void*)prev_vt_num);
        } while(res < 0 && errno == EINTR);
        close(fd);    
        char const * const ttydev = "/dev/tty0";
        fd = open(ttydev, O_RDWR | O_SYNC);
        ioctl(fd, VT_DISALLOCATE, 0);
        close(fd);
    }
}

status_t DisplayHardwareBase::ConsoleManagerThread::readyToRun()
{
    if (this->consoleFd >= 0) {
        sSignalCatcherPid = gettid();
        
        sigset_t mask;
        sigemptyset(&mask);
        sigaddset(&mask, vm.relsig);
        sigaddset(&mask, vm.acqsig);
        sigprocmask(SIG_BLOCK, &mask, NULL);

        int res = ioctl(this->consoleFd, VT_SETMODE, &vm);
        if (res<0) {
            LOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
                    this->consoleFd, errno, strerror(errno));
        }
        return NO_ERROR;
    }
    return this->consoleFd;
}

void DisplayHardwareBase::ConsoleManagerThread::requestExit()
{
    Thread::requestExit();
    if (sSignalCatcherPid != 0) {
        // wake the thread up
        kill(sSignalCatcherPid, SIGINT);
        // wait for it...
    }
}

void DisplayHardwareBase::ConsoleManagerThread::sigHandler(int sig)
{
    // resend the signal to our signal catcher thread
    LOGW("received signal %d in thread %d, resending to %d",
            sig, gettid(), sSignalCatcherPid);

    // we absolutely need the delays below because without them
    // our main thread never gets a chance to handle the signal.
    usleep(10000);
    kill(sSignalCatcherPid, sig);
    usleep(10000);
}

status_t DisplayHardwareBase::ConsoleManagerThread::releaseScreen() const
{
    int fd = this->consoleFd;
    int err = ioctl(fd, VT_RELDISP, (void*)1);
    LOGE_IF(err<0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
        fd, errno, strerror(errno));
    return (err<0) ? (-errno) : status_t(NO_ERROR);
}

bool DisplayHardwareBase::ConsoleManagerThread::threadLoop()
{
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, vm.relsig);
    sigaddset(&mask, vm.acqsig);

    int sig = 0;
    sigwait(&mask, &sig);

    if (sig == vm.relsig) {
        sp<SurfaceFlinger> flinger = mFlinger.promote();
        //LOGD("About to give-up screen, flinger = %p", flinger.get());
        if (flinger != 0)
            flinger->screenReleased(0);
    } else if (sig == vm.acqsig) {
        sp<SurfaceFlinger> flinger = mFlinger.promote();
        //LOGD("Screen about to return, flinger = %p", flinger.get());
        if (flinger != 0) 
            flinger->screenAcquired(0);
    }
    
    return true;
}

status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const
{
    return consoleFd >= 0 ? NO_ERROR : NO_INIT;
}

// ----------------------------------------------------------------------------

DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
        uint32_t displayIndex) 
    : mCanDraw(true)
{
    mDisplayEventThread = new DisplayEventThread(flinger);
    if (mDisplayEventThread->initCheck() != NO_ERROR) {
        // fall-back on the console
        mDisplayEventThread = new ConsoleManagerThread(flinger);
    }
}

DisplayHardwareBase::~DisplayHardwareBase()
{
    // request exit
    mDisplayEventThread->requestExitAndWait();
}


bool DisplayHardwareBase::canDraw() const
{
    return mCanDraw;
}

void DisplayHardwareBase::releaseScreen() const
{
    status_t err = mDisplayEventThread->releaseScreen();
    if (err >= 0) {
        //LOGD("screen given-up");
        mCanDraw = false;
    }
}

void DisplayHardwareBase::acquireScreen() const
{
    status_t err = mDisplayEventThread->acquireScreen();
    if (err >= 0) {
        //LOGD("screen returned");
        mCanDraw = true;
    }
}

}; // namespace android
