From 6652b3edcb7ef5402c05db12f477ceb23c27d6ec Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Thu, 6 Sep 2012 18:45:56 -0700 Subject: [PATCH] Watch for SurfaceFlinger death The ComposerService object wasn't watching for SurfaceFlinger restarts, which doesn't usually matter because the app framework restarts when SurfaceFlinger dies. However, mediaserver continues to run, which means its ComposerService object was trying to use a dead handle, and playback of DRM movies was failing. This adds a DeathRecipient listener and some logic to re-establish the SurfaceFlinger connection. Bug 6645813 Change-Id: I07581b881d3835601aa57d5358c8259d93bc4515 --- include/private/gui/ComposerService.h | 15 ++++++++++- libs/gui/SurfaceComposerClient.cpp | 39 +++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) 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; } // ---------------------------------------------------------------------------