diff --git a/include/private/gui/ComposerService.h b/include/private/gui/ComposerService.h index c2761b89a..ff2f9bf0f 100644 --- a/include/private/gui/ComposerService.h +++ b/include/private/gui/ComposerService.h @@ -33,13 +33,26 @@ class ISurfaceComposer; // --------------------------------------------------------------------------- +// This holds our connection to the composer service (i.e. SurfaceFlinger). +// If the remote side goes away, we will re-establish the connection. +// Users of this class should not retain the value from +// getComposerService() for an extended period. +// +// (It's not clear that using Singleton is useful here anymore.) class ComposerService : public Singleton { - // these are constants sp mComposerService; + sp mDeathObserver; + Mutex mLock; + ComposerService(); + void connectLocked(); + void composerServiceDied(); friend class Singleton; public: + + // Get a connection to the Composer Service. This will block until + // a connection is established. static sp getComposerService(); }; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 814036e3f..9b43ae837 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -46,14 +46,49 @@ ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService); ComposerService::ComposerService() : Singleton() { + Mutex::Autolock _l(mLock); + connectLocked(); +} + +void ComposerService::connectLocked() { const String16 name("SurfaceFlinger"); while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); } + assert(mComposerService != NULL); + + // Create the death listener. + class DeathObserver : public IBinder::DeathRecipient { + ComposerService& mComposerService; + virtual void binderDied(const wp& who) { + ALOGW("ComposerService remote (surfaceflinger) died [%p]", + who.unsafe_get()); + mComposerService.composerServiceDied(); + } + public: + DeathObserver(ComposerService& mgr) : mComposerService(mgr) { } + }; + + mDeathObserver = new DeathObserver(*const_cast(this)); + mComposerService->asBinder()->linkToDeath(mDeathObserver); } -sp ComposerService::getComposerService() { - return ComposerService::getInstance().mComposerService; +/*static*/ sp ComposerService::getComposerService() { + ComposerService& instance = ComposerService::getInstance(); + Mutex::Autolock _l(instance.mLock); + if (instance.mComposerService == NULL) { + ComposerService::getInstance().connectLocked(); + assert(instance.mComposerService != NULL); + ALOGD("ComposerService reconnected"); + } + return instance.mComposerService; +} + +void ComposerService::composerServiceDied() +{ + Mutex::Autolock _l(mLock); + mComposerService = NULL; + mDeathObserver = NULL; } // ---------------------------------------------------------------------------