Merge change 26691 into eclair

* changes:
  fix [2132563] stuck in boot animation (framebuffer_device_open: Failed to create flip chain)
This commit is contained in:
Android (Google) Code Review
2009-09-23 18:50:22 -04:00
4 changed files with 70 additions and 30 deletions

View File

@@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
#define LOG_TAG "BootAnimation"
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <math.h> #include <math.h>
@@ -58,13 +60,29 @@ BootAnimation::~BootAnimation() {
} }
void BootAnimation::onFirstRef() { void BootAnimation::onFirstRef() {
run("BootAnimation", PRIORITY_DISPLAY); status_t err = mSession->linkToComposerDeath(this);
LOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
if (err != NO_ERROR) {
run("BootAnimation", PRIORITY_DISPLAY);
}
} }
const sp<SurfaceComposerClient>& BootAnimation::session() const { sp<SurfaceComposerClient> BootAnimation::session() const {
return mSession; return mSession;
} }
void BootAnimation::binderDied(const wp<IBinder>& who)
{
// woah, surfaceflinger died!
LOGD("SurfaceFlinger died, exiting...");
// calling requestExit() is not enough here because the Surface code
// might be blocked on a condition variable that will never be updated.
kill( getpid(), SIGKILL );
requestExit();
}
status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets, status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
const char* name) { const char* name) {
Asset* asset = assets.open(name, Asset::ACCESS_BUFFER); Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);

View File

@@ -37,18 +37,19 @@ class AssetManager;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
class BootAnimation : public Thread class BootAnimation : public Thread, public IBinder::DeathRecipient
{ {
public: public:
BootAnimation(); BootAnimation();
virtual ~BootAnimation(); virtual ~BootAnimation();
const sp<SurfaceComposerClient>& session() const; sp<SurfaceComposerClient> session() const;
private: private:
virtual bool threadLoop(); virtual bool threadLoop();
virtual status_t readyToRun(); virtual status_t readyToRun();
virtual void onFirstRef(); virtual void onFirstRef();
virtual void binderDied(const wp<IBinder>& who);
struct Texture { struct Texture {
GLint w; GLint w;

View File

@@ -20,6 +20,8 @@
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <binder/IBinder.h>
#include <utils/SortedVector.h> #include <utils/SortedVector.h>
#include <utils/RefBase.h> #include <utils/RefBase.h>
#include <utils/threads.h> #include <utils/threads.h>
@@ -106,6 +108,8 @@ public:
static ssize_t getDisplayHeight(DisplayID dpy); static ssize_t getDisplayHeight(DisplayID dpy);
static ssize_t getDisplayOrientation(DisplayID dpy); static ssize_t getDisplayOrientation(DisplayID dpy);
status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0);
private: private:
friend class Surface; friend class Surface;

View File

@@ -62,34 +62,42 @@ static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions;
static sp<IMemoryHeap> gServerCblkMemory; static sp<IMemoryHeap> gServerCblkMemory;
static volatile surface_flinger_cblk_t* gServerCblk; static volatile surface_flinger_cblk_t* gServerCblk;
const sp<ISurfaceComposer>& _get_surface_manager() static sp<ISurfaceComposer> getComposerService()
{ {
if (gSurfaceManager != 0) { sp<ISurfaceComposer> sc;
return gSurfaceManager;
}
sp<IBinder> binder;
sp<IServiceManager> sm = defaultServiceManager();
do {
binder = sm->getService(String16("SurfaceFlinger"));
if (binder == 0) {
LOGW("SurfaceFlinger not published, waiting...");
usleep(500000); // 0.5 s
}
} while(binder == 0);
sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
Mutex::Autolock _l(gLock); Mutex::Autolock _l(gLock);
if (gSurfaceManager == 0) { if (gSurfaceManager != 0) {
gSurfaceManager = sc; sc = gSurfaceManager;
} else {
// release the lock while we're waiting...
gLock.unlock();
sp<IBinder> binder;
sp<IServiceManager> sm = defaultServiceManager();
do {
binder = sm->getService(String16("SurfaceFlinger"));
if (binder == 0) {
LOGW("SurfaceFlinger not published, waiting...");
usleep(500000); // 0.5 s
}
} while(binder == 0);
// grab the lock again for updating gSurfaceManager
gLock.lock();
if (gSurfaceManager == 0) {
sc = interface_cast<ISurfaceComposer>(binder);
gSurfaceManager = sc;
} else {
sc = gSurfaceManager;
}
} }
return gSurfaceManager; return sc;
} }
static volatile surface_flinger_cblk_t const * get_cblk() static volatile surface_flinger_cblk_t const * get_cblk()
{ {
if (gServerCblk == 0) { if (gServerCblk == 0) {
const sp<ISurfaceComposer>& sm(_get_surface_manager()); sp<ISurfaceComposer> sm(getComposerService());
Mutex::Autolock _l(gLock); Mutex::Autolock _l(gLock);
if (gServerCblk == 0) { if (gServerCblk == 0) {
gServerCblkMemory = sm->getCblk(); gServerCblkMemory = sm->getCblk();
@@ -112,7 +120,7 @@ static inline int compare_type( const layer_state_t& lhs,
SurfaceComposerClient::SurfaceComposerClient() SurfaceComposerClient::SurfaceComposerClient()
{ {
const sp<ISurfaceComposer>& sm(_get_surface_manager()); sp<ISurfaceComposer> sm(getComposerService());
if (sm == 0) { if (sm == 0) {
_init(0, 0); _init(0, 0);
return; return;
@@ -133,6 +141,15 @@ SurfaceComposerClient::SurfaceComposerClient(
_init(sm, interface_cast<ISurfaceFlingerClient>(conn)); _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
} }
status_t SurfaceComposerClient::linkToComposerDeath(
const sp<IBinder::DeathRecipient>& recipient,
void* cookie, uint32_t flags)
{
sp<ISurfaceComposer> sm(getComposerService());
return sm->asBinder()->linkToDeath(recipient, cookie, flags);
}
void SurfaceComposerClient::_init( void SurfaceComposerClient::_init(
const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn) const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
{ {
@@ -183,7 +200,7 @@ SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
if (client == 0) { if (client == 0) {
// Need to make a new client. // Need to make a new client.
const sp<ISurfaceComposer>& sm(_get_surface_manager()); sp<ISurfaceComposer> sm(getComposerService());
client = new SurfaceComposerClient(sm, conn); client = new SurfaceComposerClient(sm, conn);
if (client != 0 && client->initCheck() == NO_ERROR) { if (client != 0 && client->initCheck() == NO_ERROR) {
Mutex::Autolock _l(gLock); Mutex::Autolock _l(gLock);
@@ -377,7 +394,7 @@ void SurfaceComposerClient::closeGlobalTransaction()
const size_t N = clients.size(); const size_t N = clients.size();
VERBOSE("closeGlobalTransaction (%ld clients)", N); VERBOSE("closeGlobalTransaction (%ld clients)", N);
const sp<ISurfaceComposer>& sm(_get_surface_manager()); sp<ISurfaceComposer> sm(getComposerService());
sm->openGlobalTransaction(); sm->openGlobalTransaction();
for (size_t i=0; i<N; i++) { for (size_t i=0; i<N; i++) {
clients[i]->closeTransaction(); clients[i]->closeTransaction();
@@ -389,20 +406,20 @@ void SurfaceComposerClient::closeGlobalTransaction()
status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags) status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
{ {
const sp<ISurfaceComposer>& sm(_get_surface_manager()); sp<ISurfaceComposer> sm(getComposerService());
return sm->freezeDisplay(dpy, flags); return sm->freezeDisplay(dpy, flags);
} }
status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags) status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
{ {
const sp<ISurfaceComposer>& sm(_get_surface_manager()); sp<ISurfaceComposer> sm(getComposerService());
return sm->unfreezeDisplay(dpy, flags); return sm->unfreezeDisplay(dpy, flags);
} }
int SurfaceComposerClient::setOrientation(DisplayID dpy, int SurfaceComposerClient::setOrientation(DisplayID dpy,
int orientation, uint32_t flags) int orientation, uint32_t flags)
{ {
const sp<ISurfaceComposer>& sm(_get_surface_manager()); sp<ISurfaceComposer> sm(getComposerService());
return sm->setOrientation(dpy, orientation, flags); return sm->setOrientation(dpy, orientation, flags);
} }