Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6652b3ed authored by Andy McFadden's avatar Andy McFadden
Browse files

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
parent 55882dea
Loading
Loading
Loading
Loading
+14 −1
Original line number Original line Diff line number Diff line
@@ -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>
class ComposerService : public Singleton<ComposerService>
{
{
    // these are constants
    sp<ISurfaceComposer> mComposerService;
    sp<ISurfaceComposer> mComposerService;
    sp<IBinder::DeathRecipient> mDeathObserver;
    Mutex mLock;

    ComposerService();
    ComposerService();
    void connectLocked();
    void composerServiceDied();
    friend class Singleton<ComposerService>;
    friend class Singleton<ComposerService>;
public:
public:

    // Get a connection to the Composer Service.  This will block until
    // a connection is established.
    static sp<ISurfaceComposer> getComposerService();
    static sp<ISurfaceComposer> getComposerService();
};
};


+37 −2
Original line number Original line Diff line number Diff line
@@ -46,14 +46,49 @@ ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);


ComposerService::ComposerService()
ComposerService::ComposerService()
: Singleton<ComposerService>() {
: Singleton<ComposerService>() {
    Mutex::Autolock _l(mLock);
    connectLocked();
}

void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
        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) { }
    };


sp<ISurfaceComposer> ComposerService::getComposerService() {
    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
    return ComposerService::getInstance().mComposerService;
    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;
}

void ComposerService::composerServiceDied()
{
    Mutex::Autolock _l(mLock);
    mComposerService = NULL;
    mDeathObserver = NULL;
}
}


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------