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

Commit 97b9c863 authored by Robert Carr's avatar Robert Carr
Browse files

Surface: Add force disconnection method.

Add a new method forceScopedDisconnect to Surface. This will
be used by the framework to force disconnection at times where
the underlying GraphicBufferProducer may be about to be reused.
This is scoped by PID to avoid conflicting with remote producers.

Bug: 30236166
Change-Id: I857216483c0b550f240b3baea41977cbc58a67ed
parent 66986783
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -182,6 +182,8 @@ private:
    // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated
    // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated
    // by the connect and disconnect methods.
    // by the connect and disconnect methods.
    int mConnectedApi;
    int mConnectedApi;
    // PID of the process which last successfully called connect(...)
    pid_t mConnectedPid;


    // mConnectedProducerToken is used to set a binder death notification on
    // mConnectedProducerToken is used to set a binder death notification on
    // the producer.
    // the producer.
+2 −9
Original line number Original line Diff line number Diff line
@@ -135,15 +135,8 @@ public:
    virtual status_t connect(const sp<IProducerListener>& listener,
    virtual status_t connect(const sp<IProducerListener>& listener,
            int api, bool producerControlledByApp, QueueBufferOutput* output);
            int api, bool producerControlledByApp, QueueBufferOutput* output);


    // disconnect attempts to disconnect a producer API from the BufferQueue.
    // See IGraphicBufferProducer::disconnect
    // Calling this method will cause any subsequent calls to other
    virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api);
    // IGraphicBufferProducer methods to fail except for getAllocator and connect.
    // Successfully calling connect after this will allow the other methods to
    // succeed again.
    //
    // This method will fail if the the BufferQueue is not currently
    // connected to the specified producer API.
    virtual status_t disconnect(int api);


    // Attaches a sideband buffer stream to the IGraphicBufferProducer.
    // Attaches a sideband buffer stream to the IGraphicBufferProducer.
    //
    //
+11 −4
Original line number Original line Diff line number Diff line
@@ -458,17 +458,24 @@ public:
    virtual status_t connect(const sp<IProducerListener>& listener,
    virtual status_t connect(const sp<IProducerListener>& listener,
            int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;
            int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;


    enum class DisconnectMode {
        // Disconnect only the specified API.
        Api,
        // Disconnect any API originally connected from the process calling disconnect.
        AllLocal
    };

    // disconnect attempts to disconnect a client API from the
    // disconnect attempts to disconnect a client API from the
    // IGraphicBufferProducer.  Calling this method will cause any subsequent
    // IGraphicBufferProducer.  Calling this method will cause any subsequent
    // calls to other IGraphicBufferProducer methods to fail except for
    // calls to other IGraphicBufferProducer methods to fail except for
    // getAllocator and connect.  Successfully calling connect after this will
    // getAllocator and connect.  Successfully calling connect after this will
    // allow the other methods to succeed again.
    // allow the other methods to succeed again.
    //
    //
    // This method will fail if the the IGraphicBufferProducer is not currently
    // connected to the specified client API.
    //
    // The api should be one of the NATIVE_WINDOW_API_* values in <window.h>
    // The api should be one of the NATIVE_WINDOW_API_* values in <window.h>
    //
    //
    // Alternatively if mode is AllLocal, then the API value is ignored, and any API
    // connected from the same PID calling disconnect will be disconnected.
    //
    // Disconnecting from an abandoned IGraphicBufferProducer is legal and
    // Disconnecting from an abandoned IGraphicBufferProducer is legal and
    // is considered a no-op.
    // is considered a no-op.
    //
    //
@@ -477,7 +484,7 @@ public:
    //             * the api specified does not match the one that was connected
    //             * the api specified does not match the one that was connected
    //             * api was out of range (see above).
    //             * api was out of range (see above).
    // * DEAD_OBJECT - the token is hosted by an already-dead process
    // * DEAD_OBJECT - the token is hosted by an already-dead process
    virtual status_t disconnect(int api) = 0;
    virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) = 0;


    // Attaches a sideband buffer stream to the IGraphicBufferProducer.
    // Attaches a sideband buffer stream to the IGraphicBufferProducer.
    //
    //
+4 −1
Original line number Original line Diff line number Diff line
@@ -203,7 +203,6 @@ protected:
    virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);
    virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);


    virtual int connect(int api);
    virtual int connect(int api);
    virtual int disconnect(int api);
    virtual int setBufferCount(int bufferCount);
    virtual int setBufferCount(int bufferCount);
    virtual int setBuffersDimensions(uint32_t width, uint32_t height);
    virtual int setBuffersDimensions(uint32_t width, uint32_t height);
    virtual int setBuffersUserDimensions(uint32_t width, uint32_t height);
    virtual int setBuffersUserDimensions(uint32_t width, uint32_t height);
@@ -217,6 +216,10 @@ protected:
    virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);
    virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);


public:
public:
    virtual int disconnect(int api,
            IGraphicBufferProducer::DisconnectMode mode =
                    IGraphicBufferProducer::DisconnectMode::Api);

    virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers);
    virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers);
    virtual int setAsyncMode(bool async);
    virtual int setAsyncMode(bool async);
    virtual int setSharedBufferMode(bool sharedBufferMode);
    virtual int setSharedBufferMode(bool sharedBufferMode);
+12 −2
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@


#define EGL_EGLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES


#include <binder/IPCThreadState.h>
#include <gui/BufferItem.h>
#include <gui/BufferItem.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
#include <gui/BufferQueueProducer.h>
@@ -1130,7 +1131,7 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
            status = BAD_VALUE;
            status = BAD_VALUE;
            break;
            break;
    }
    }

    mCore->mConnectedPid = IPCThreadState::self()->getCallingPid();
    mCore->mBufferHasBeenQueued = false;
    mCore->mBufferHasBeenQueued = false;
    mCore->mDequeueBufferCannotBlock = false;
    mCore->mDequeueBufferCannotBlock = false;
    if (mDequeueTimeout < 0) {
    if (mDequeueTimeout < 0) {
@@ -1143,7 +1144,7 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
    return status;
    return status;
}
}


status_t BufferQueueProducer::disconnect(int api) {
status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("disconnect: api %d", api);
    BQ_LOGV("disconnect: api %d", api);


@@ -1151,6 +1152,14 @@ status_t BufferQueueProducer::disconnect(int api) {
    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        Mutex::Autolock lock(mCore->mMutex);

        if (mode == DisconnectMode::AllLocal) {
            if (IPCThreadState::self()->getCallingPid() != mCore->mConnectedPid) {
                return NO_ERROR;
            }
            api = BufferQueueCore::CURRENTLY_CONNECTED_API;
        }

        mCore->waitWhileAllocatingLocked();
        mCore->waitWhileAllocatingLocked();


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
@@ -1189,6 +1198,7 @@ status_t BufferQueueProducer::disconnect(int api) {
                            BufferQueueCore::INVALID_BUFFER_SLOT;
                            BufferQueueCore::INVALID_BUFFER_SLOT;
                    mCore->mConnectedProducerListener = NULL;
                    mCore->mConnectedProducerListener = NULL;
                    mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
                    mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
                    mCore->mConnectedPid = -1;
                    mCore->mSidebandStream.clear();
                    mCore->mSidebandStream.clear();
                    mCore->mDequeueCondition.broadcast();
                    mCore->mDequeueCondition.broadcast();
                    listener = mCore->mConsumerListener;
                    listener = mCore->mConsumerListener;
Loading