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

Commit 8e533069 authored by Colin Cross's avatar Colin Cross
Browse files

surfaceflinger: replace early suspend with binder call from PowerManager

SurfaceFlinger will no longer directly synchronize with early suspend.
Instead, PowerManagerService will synchronize with SurfaceFlinger to
ensure that a black frame has been drawn on the display, and then
trigger all early suspend handlers.

Change-Id: I07acdd628440d23fdb69db94319ec5d65d3f4919
parent 1e339878
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -139,6 +139,12 @@ public:

    /* return an IDisplayEventConnection */
    virtual sp<IDisplayEventConnection> createDisplayEventConnection() = 0;

    /* triggers screen off and waits for it to complete */
    virtual void blank() = 0;

    /* triggers screen on and waits for it to complete */
    virtual void unblank() = 0;
};

// ----------------------------------------------------------------------------
@@ -160,6 +166,8 @@ public:
        TURN_ELECTRON_BEAM_ON,
        AUTHENTICATE_SURFACE,
        CREATE_DISPLAY_EVENT_CONNECTION,
        BLANK,
        UNBLANK,
    };

    virtual status_t    onTransact( uint32_t code,
+22 −0
Original line number Diff line number Diff line
@@ -193,6 +193,20 @@ public:
        result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
        return result;
    }

    virtual void blank()
    {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        remote()->transact(BnSurfaceComposer::BLANK, data, &reply);
    }

    virtual void unblank()
    {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        remote()->transact(BnSurfaceComposer::UNBLANK, data, &reply);
    }
};

IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -279,6 +293,14 @@ status_t BnSurfaceComposer::onTransact(
            reply->writeStrongBinder(connection->asBinder());
            return NO_ERROR;
        } break;
        case BLANK: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            blank();
        } break;
        case UNBLANK: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            unblank();
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+0 −78
Original line number Diff line number Diff line
@@ -30,91 +30,13 @@
// ----------------------------------------------------------------------------
namespace android {

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

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

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

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

status_t DisplayHardwareBase::DisplayEventThread::initCheck() const {
    return ((access(kSleepFileName, R_OK) == 0 &&
            access(kWakeFileName, R_OK) == 0)) ? NO_ERROR : NO_INIT;
}

bool DisplayHardwareBase::DisplayEventThread::threadLoop() {

    if (waitForFbSleep() == NO_ERROR) {
        sp<SurfaceFlinger> flinger = mFlinger.promote();
        ALOGD("About to give-up screen, flinger = %p", flinger.get());
        if (flinger != 0) {
            flinger->screenReleased();
        }
        if (waitForFbWake() == NO_ERROR) {
            ALOGD("Screen about to return, flinger = %p", flinger.get());
            if (flinger != 0) {
                flinger->screenAcquired();
            }
            return true;
        }
    }

    // error, exit the thread
    return false;
}

status_t DisplayHardwareBase::DisplayEventThread::waitForFbSleep() {
    int err = 0;
    char buf;
    int fd = open(kSleepFileName, O_RDONLY, 0);
    // if the file doesn't exist, the error will be caught in read() below
    do {
        err = read(fd, &buf, 1);
    } while (err < 0 && errno == EINTR);
    close(fd);
    ALOGE_IF(err<0, "*** ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
    return err < 0 ? -errno : int(NO_ERROR);
}

status_t DisplayHardwareBase::DisplayEventThread::waitForFbWake() {
    int err = 0;
    char buf;
    int fd = open(kWakeFileName, O_RDONLY, 0);
    // if the file doesn't exist, the error will be caught in read() below
    do {
        err = read(fd, &buf, 1);
    } while (err < 0 && errno == EINTR);
    close(fd);
    ALOGE_IF(err<0, "*** ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
    return err < 0 ? -errno : int(NO_ERROR);
}

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

DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
        uint32_t displayIndex) 
{
    mScreenAcquired = true;
    mDisplayEventThread = new DisplayEventThread(flinger);
}

void DisplayHardwareBase::startSleepManagement() const {
    if (mDisplayEventThread->initCheck() == NO_ERROR) {
        mDisplayEventThread->run("DisplayEventThread", PRIORITY_URGENT_DISPLAY);
    } else {
        ALOGW("/sys/power/wait_for_fb_{wake|sleep} don't exist");
    }
}

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

bool DisplayHardwareBase::canDraw() const {
+6 −3
Original line number Diff line number Diff line
@@ -297,7 +297,6 @@ status_t SurfaceFlinger::readyToRun()
    // start the EventThread
    mEventThread = new EventThread(this);
    mEventQueue.setEventThread(mEventThread);
    hw.startSleepManagement();

    /*
     *  We're now ready to accept clients...
@@ -1363,6 +1362,7 @@ uint32_t SurfaceFlinger::setClientStateLocked(
// ---------------------------------------------------------------------------

void SurfaceFlinger::onScreenAcquired() {
    ALOGD("Screen about to return, flinger = %p", this);
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    hw.acquireScreen();
    mEventThread->onScreenAcquired();
@@ -1374,6 +1374,7 @@ void SurfaceFlinger::onScreenAcquired() {
}

void SurfaceFlinger::onScreenReleased() {
    ALOGD("About to give-up screen, flinger = %p", this);
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    if (hw.isScreenAcquired()) {
        mEventThread->onScreenReleased();
@@ -1382,7 +1383,7 @@ void SurfaceFlinger::onScreenReleased() {
    }
}

void SurfaceFlinger::screenAcquired() {
void SurfaceFlinger::unblank() {
    class MessageScreenAcquired : public MessageBase {
        SurfaceFlinger* flinger;
    public:
@@ -1396,7 +1397,7 @@ void SurfaceFlinger::screenAcquired() {
    postMessageSync(msg);
}

void SurfaceFlinger::screenReleased() {
void SurfaceFlinger::blank() {
    class MessageScreenReleased : public MessageBase {
        SurfaceFlinger* flinger;
    public:
@@ -1654,6 +1655,8 @@ status_t SurfaceFlinger::onTransact(
        case BOOT_FINISHED:
        case TURN_ELECTRON_BEAM_OFF:
        case TURN_ELECTRON_BEAM_ON:
        case BLANK:
        case UNBLANK:
        {
            // codes that require permission check
            IPCThreadState* ipc = IPCThreadState::self();
+2 −3
Original line number Diff line number Diff line
@@ -182,11 +182,10 @@ public:
    virtual status_t                    turnElectronBeamOff(int32_t mode);
    virtual status_t                    turnElectronBeamOn(int32_t mode);


            // called when screen needs to turn off
            void screenReleased();
    virtual void                        blank();
            // called when screen is turning back on
            void screenAcquired();
    virtual void                        unblank();

            // called on the main thread in response to screenReleased()
            void onScreenReleased();