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
This commit is contained in:
parent
1e339878c1
commit
8e533069e5
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue