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

Commit 02b62df7 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "Make sure do disconnect from a BQ when its client dies." into klp-dev

parents fca43392 365857df
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <binder/IBinder.h>

#include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferAlloc.h>
#include <gui/IGraphicBufferProducer.h>
@@ -35,7 +37,9 @@
namespace android {
// ----------------------------------------------------------------------------

class BufferQueue : public BnGraphicBufferProducer, public BnGraphicBufferConsumer {
class BufferQueue : public BnGraphicBufferProducer,
                    public BnGraphicBufferConsumer,
                    private IBinder::DeathRecipient {
public:
    enum { MIN_UNDEQUEUED_BUFFERS = 2 };
    enum { NUM_BUFFER_SLOTS = 32 };
@@ -78,6 +82,12 @@ public:
    BufferQueue(const sp<IGraphicBufferAlloc>& allocator = NULL);
    virtual ~BufferQueue();

    /*
     * IBinder::DeathRecipient interface
     */

    virtual void binderDied(const wp<IBinder>& who);

    /*
     * IGraphicBufferProducer interface
     */
@@ -184,7 +194,8 @@ public:
    // it's still connected to a producer).
    //
    // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU).
    virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output);
    virtual status_t connect(const sp<IBinder>& token,
            int api, bool producerControlledByApp, QueueBufferOutput* output);

    // disconnect attempts to disconnect a producer API from the BufferQueue.
    // Calling this method will cause any subsequent calls to other
@@ -552,6 +563,9 @@ private:

    // mTransformHint is used to optimize for screen rotations
    uint32_t mTransformHint;

    // mConnectedProducerToken is used to set a binder death notification on the producer
    sp<IBinder> mConnectedProducerToken;
};

// ----------------------------------------------------------------------------
+5 −2
Original line number Diff line number Diff line
@@ -189,8 +189,11 @@ public:
    //
    // outWidth, outHeight and outTransform are filled with the default width
    // and height of the window and current transform applied to buffers,
    // respectively.
    virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;
    // respectively. The token needs to be any binder object that lives in the
    // producer process -- it is solely used for obtaining a death notification
    // when the producer is killed.
    virtual status_t connect(const sp<IBinder>& token,
            int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;

    // disconnect attempts to disconnect a client API from the
    // IGraphicBufferProducer.  Calling this method will cause any subsequent
+29 −3
Original line number Diff line number Diff line
@@ -635,7 +635,9 @@ void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) {
    mDequeueCondition.broadcast();
}

status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBufferOutput* output) {

status_t BufferQueue::connect(const sp<IBinder>& token,
        int api, bool producerControlledByApp, QueueBufferOutput* output) {
    ATRACE_CALL();
    ST_LOGV("connect: api=%d producerControlledByApp=%s", api,
            producerControlledByApp ? "true" : "false");
@@ -663,8 +665,14 @@ status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBuffer
                err = -EINVAL;
            } else {
                mConnectedApi = api;
                output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
                        mQueue.size());
                output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size());

                // set-up a death notification so that we can disconnect automatically
                // when/if the remote producer dies.
                // This will fail with INVALID_OPERATION if the "token" is local to our process.
                if (token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)) == NO_ERROR) {
                    mConnectedProducerToken = token;
                }
            }
            break;
        default:
@@ -678,6 +686,16 @@ status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBuffer
    return err;
}

void BufferQueue::binderDied(const wp<IBinder>& who) {
    // If we're here, it means that a producer we were connected to died.
    // We're GUARANTEED that we still are connected to it because it has no other way
    // to get disconnected -- or -- we wouldn't be here because we're removing this
    // callback upon disconnect. Therefore, it's okay to read mConnectedApi without
    // synchronization here.
    int api = mConnectedApi;
    this->disconnect(api);
}

status_t BufferQueue::disconnect(int api) {
    ATRACE_CALL();
    ST_LOGV("disconnect: api=%d", api);
@@ -701,6 +719,14 @@ status_t BufferQueue::disconnect(int api) {
            case NATIVE_WINDOW_API_CAMERA:
                if (mConnectedApi == api) {
                    freeAllBuffersLocked();
                    // remove our death notification callback if we have one
                    sp<IBinder> token = mConnectedProducerToken;
                    if (token != NULL) {
                        // this can fail if we're here because of the death notification
                        // either way, we just ignore.
                        token->unlinkToDeath(static_cast<IBinder::DeathRecipient*>(this));
                    }
                    mConnectedProducerToken = NULL;
                    mConnectedApi = NO_CONNECTED_API;
                    mDequeueCondition.broadcast();
                    listener = mConsumerListener;
+5 −3
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ enum {
    DISCONNECT,
};


class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
{
public:
@@ -139,9 +138,11 @@ public:
        return result;
    }

    virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output) {
    virtual status_t connect(const sp<IBinder>& token,
            int api, bool producerControlledByApp, QueueBufferOutput* output) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeStrongBinder(token);
        data.writeInt32(api);
        data.writeInt32(producerControlledByApp);
        status_t result = remote()->transact(CONNECT, data, &reply);
@@ -241,12 +242,13 @@ status_t BnGraphicBufferProducer::onTransact(
        } break;
        case CONNECT: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            sp<IBinder> token = data.readStrongBinder();
            int api = data.readInt32();
            bool producerControlledByApp = data.readInt32();
            QueueBufferOutput* const output =
                    reinterpret_cast<QueueBufferOutput *>(
                            reply->writeInplace(sizeof(QueueBufferOutput)));
            status_t res = connect(api, producerControlledByApp, output);
            status_t res = connect(token, api, producerControlledByApp, output);
            reply->writeInt32(res);
            return NO_ERROR;
        } break;
+3 −1
Original line number Diff line number Diff line
@@ -490,9 +490,10 @@ int Surface::dispatchUnlockAndPost(va_list args) {
int Surface::connect(int api) {
    ATRACE_CALL();
    ALOGV("Surface::connect");
    static sp<BBinder> sLife = new BBinder();
    Mutex::Autolock lock(mMutex);
    IGraphicBufferProducer::QueueBufferOutput output;
    int err = mGraphicBufferProducer->connect(api, mProducerControlledByApp, &output);
    int err = mGraphicBufferProducer->connect(sLife, api, mProducerControlledByApp, &output);
    if (err == NO_ERROR) {
        uint32_t numPendingBuffers = 0;
        output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
@@ -505,6 +506,7 @@ int Surface::connect(int api) {
    return err;
}


int Surface::disconnect(int api) {
    ATRACE_CALL();
    ALOGV("Surface::disconnect");
Loading