diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h index 269959c9b..8701928eb 100644 --- a/include/ui/SurfaceComposerClient.h +++ b/include/ui/SurfaceComposerClient.h @@ -20,6 +20,8 @@ #include #include +#include + #include #include #include @@ -106,6 +108,8 @@ public: static ssize_t getDisplayHeight(DisplayID dpy); static ssize_t getDisplayOrientation(DisplayID dpy); + status_t linkToComposerDeath(const sp& recipient, + void* cookie = NULL, uint32_t flags = 0); private: friend class Surface; diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp index 8401cb696..3baa2817a 100644 --- a/libs/ui/SurfaceComposerClient.cpp +++ b/libs/ui/SurfaceComposerClient.cpp @@ -62,34 +62,42 @@ static SortedVector > gOpenTransactions; static sp gServerCblkMemory; static volatile surface_flinger_cblk_t* gServerCblk; -const sp& _get_surface_manager() +static sp getComposerService() { - if (gSurfaceManager != 0) { - return gSurfaceManager; - } - - sp binder; - sp 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 sc(interface_cast(binder)); - + sp sc; Mutex::Autolock _l(gLock); - if (gSurfaceManager == 0) { - gSurfaceManager = sc; + if (gSurfaceManager != 0) { + sc = gSurfaceManager; + } else { + // release the lock while we're waiting... + gLock.unlock(); + + sp binder; + sp 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(binder); + gSurfaceManager = sc; + } else { + sc = gSurfaceManager; + } } - return gSurfaceManager; + return sc; } static volatile surface_flinger_cblk_t const * get_cblk() { if (gServerCblk == 0) { - const sp& sm(_get_surface_manager()); + sp sm(getComposerService()); Mutex::Autolock _l(gLock); if (gServerCblk == 0) { gServerCblkMemory = sm->getCblk(); @@ -112,7 +120,7 @@ static inline int compare_type( const layer_state_t& lhs, SurfaceComposerClient::SurfaceComposerClient() { - const sp& sm(_get_surface_manager()); + sp sm(getComposerService()); if (sm == 0) { _init(0, 0); return; @@ -133,6 +141,15 @@ SurfaceComposerClient::SurfaceComposerClient( _init(sm, interface_cast(conn)); } + +status_t SurfaceComposerClient::linkToComposerDeath( + const sp& recipient, + void* cookie, uint32_t flags) +{ + sp sm(getComposerService()); + return sm->asBinder()->linkToDeath(recipient, cookie, flags); +} + void SurfaceComposerClient::_init( const sp& sm, const sp& conn) { @@ -183,7 +200,7 @@ SurfaceComposerClient::clientForConnection(const sp& conn) if (client == 0) { // Need to make a new client. - const sp& sm(_get_surface_manager()); + sp sm(getComposerService()); client = new SurfaceComposerClient(sm, conn); if (client != 0 && client->initCheck() == NO_ERROR) { Mutex::Autolock _l(gLock); @@ -377,7 +394,7 @@ void SurfaceComposerClient::closeGlobalTransaction() const size_t N = clients.size(); VERBOSE("closeGlobalTransaction (%ld clients)", N); - const sp& sm(_get_surface_manager()); + sp sm(getComposerService()); sm->openGlobalTransaction(); for (size_t i=0; icloseTransaction(); @@ -389,20 +406,20 @@ void SurfaceComposerClient::closeGlobalTransaction() status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags) { - const sp& sm(_get_surface_manager()); + sp sm(getComposerService()); return sm->freezeDisplay(dpy, flags); } status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags) { - const sp& sm(_get_surface_manager()); + sp sm(getComposerService()); return sm->unfreezeDisplay(dpy, flags); } int SurfaceComposerClient::setOrientation(DisplayID dpy, int orientation, uint32_t flags) { - const sp& sm(_get_surface_manager()); + sp sm(getComposerService()); return sm->setOrientation(dpy, orientation, flags); }