Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9071ad3 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "remove support for console in SurfaceFlinger"

parents 5791e5b2 3d031507
Loading
Loading
Loading
Loading
+4 −245
Original line number Diff line number Diff line
@@ -37,24 +37,11 @@
#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";
static char const * const kSleepFileName = "/sys/power/wait_for_fb_sleep";
static char const * const kWakeFileName  = "/sys/power/wait_for_fb_wake";

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

@@ -122,237 +109,13 @@ status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const

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;
    return ((access(kSleepFileName, R_OK) == 0 &&
            access(kWakeFileName, R_OK) == 0)) ? NO_ERROR : NO_INIT;
}

// ----------------------------------------------------------------------------
@@ -362,10 +125,6 @@ DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
    : mCanDraw(true), mScreenAcquired(true)
{
    mDisplayEventThread = new DisplayEventThread(flinger);
    if (mDisplayEventThread->initCheck() != NO_ERROR) {
        // fall-back on the console
        mDisplayEventThread = new ConsoleManagerThread(flinger);
    }
}

DisplayHardwareBase::~DisplayHardwareBase()
+0 −18
Original line number Diff line number Diff line
@@ -73,24 +73,6 @@ private:
        virtual status_t initCheck() const;
    };

    class ConsoleManagerThread : public DisplayEventThreadBase 
    {
        int consoleFd;
        int vt_num;
        int prev_vt_num;
        vt_mode vm;
        static void sigHandler(int sig);
        static pid_t sSignalCatcherPid;
    public:
                ConsoleManagerThread(const sp<SurfaceFlinger>& flinger);
        virtual ~ConsoleManagerThread();
        virtual bool threadLoop();
        virtual status_t readyToRun();
        virtual void requestExit();
        virtual status_t releaseScreen() const;
        virtual status_t initCheck() const;
    };

    sp<DisplayEventThreadBase>  mDisplayEventThread;
    mutable int                 mCanDraw;
    mutable int                 mScreenAcquired;