Loading services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp +4 −245 Original line number Diff line number Diff line Loading @@ -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"; // ---------------------------------------------------------------------------- Loading Loading @@ -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; } // ---------------------------------------------------------------------------- Loading @@ -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() Loading services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h +0 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp +4 −245 Original line number Diff line number Diff line Loading @@ -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"; // ---------------------------------------------------------------------------- Loading Loading @@ -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; } // ---------------------------------------------------------------------------- Loading @@ -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() Loading
services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h +0 −18 Original line number Diff line number Diff line Loading @@ -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; Loading