Merge "Watch for SurfaceFlinger death" into jb-mr1-dev
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 @@
 
 // ---------------------------------------------------------------------------
 
+// 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 @@
 
 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);
 }
 
-sp<ISurfaceComposer> ComposerService::getComposerService() {
-    return ComposerService::getInstance().mComposerService;
+/*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;
+}
+
+void ComposerService::composerServiceDied()
+{
+    Mutex::Autolock _l(mLock);
+    mComposerService = NULL;
+    mDeathObserver = NULL;
 }
 
 // ---------------------------------------------------------------------------