summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/private/gui/ComposerService.h15
-rw-r--r--libs/gui/SurfaceComposerClient.cpp39
2 files changed, 51 insertions, 3 deletions
diff --git a/include/private/gui/ComposerService.h b/include/private/gui/ComposerService.h
index c2761b8..ff2f9bf 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<ComposerService>
{
- // these are constants
sp<ISurfaceComposer> mComposerService;
+ sp<IBinder::DeathRecipient> mDeathObserver;
+ Mutex mLock;
+
ComposerService();
+ void connectLocked();
+ void composerServiceDied();
friend class Singleton<ComposerService>;
public:
+
+ // Get a connection to the Composer Service. This will block until
+ // a connection is established.
static sp<ISurfaceComposer> getComposerService();
};
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 814036e..9b43ae8 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -46,14 +46,49 @@ ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
ComposerService::ComposerService()
: Singleton<ComposerService>() {
+ 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<IBinder>& who) {
+ ALOGW("ComposerService remote (surfaceflinger) died [%p]",
+ who.unsafe_get());
+ mComposerService.composerServiceDied();
+ }
+ public:
+ DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
+ };
+
+ mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
+ mComposerService->asBinder()->linkToDeath(mDeathObserver);
+}
+
+/*static*/ sp<ISurfaceComposer> 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;
}
-sp<ISurfaceComposer> ComposerService::getComposerService() {
- return ComposerService::getInstance().mComposerService;
+void ComposerService::composerServiceDied()
+{
+ Mutex::Autolock _l(mLock);
+ mComposerService = NULL;
+ mDeathObserver = NULL;
}
// ---------------------------------------------------------------------------