Loading include/gui/BufferQueueCore.h +5 −1 Original line number Diff line number Diff line Loading @@ -185,8 +185,12 @@ private: // PID of the process which last successfully called connect(...) pid_t mConnectedPid; // mConnectedProducerToken is used to set a binder death notification on // mLinkedToDeath is used to set a binder death notification on // the producer. sp<IProducerListener> mLinkedToDeath; // mConnectedProducerListener is used to handle the onBufferReleased // notification. sp<IProducerListener> mConnectedProducerListener; // mSlots is an array of buffer slots that must be mirrored on the producer Loading include/gui/IProducerListener.h +3 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ public: // This is called without any lock held and can be called concurrently by // multiple threads. virtual void onBufferReleased() = 0; // Asynchronous virtual bool needsReleaseNotify() = 0; }; class IProducerListener : public ProducerListener, public IInterface Loading @@ -54,12 +55,14 @@ class BnProducerListener : public BnInterface<IProducerListener> public: virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); virtual bool needsReleaseNotify(); }; class DummyProducerListener : public BnProducerListener { public: virtual void onBufferReleased() {} virtual bool needsReleaseNotify() { return false; } }; } // namespace android Loading libs/gui/BufferQueueCore.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) : mConsumerListener(), mConsumerUsageBits(0), mConnectedApi(NO_CONNECTED_API), mLinkedToDeath(), mConnectedProducerListener(), mSlots(), mQueue(), Loading libs/gui/BufferQueueProducer.cpp +17 −12 Original line number Diff line number Diff line Loading @@ -1113,18 +1113,22 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, static_cast<uint32_t>(mCore->mQueue.size()), mCore->mFrameCounter + 1); if (listener != NULL) { // Set up a death notification so that we can disconnect // automatically if the remote producer dies if (listener != NULL && IInterface::asBinder(listener)->remoteBinder() != NULL) { if (IInterface::asBinder(listener)->remoteBinder() != NULL) { status = IInterface::asBinder(listener)->linkToDeath( static_cast<IBinder::DeathRecipient*>(this)); if (status != NO_ERROR) { BQ_LOGE("connect: linkToDeath failed: %s (%d)", strerror(-status), status); } mCore->mLinkedToDeath = listener; } if (listener->needsReleaseNotify()) { mCore->mConnectedProducerListener = listener; } } break; default: BQ_LOGE("connect: unknown API %d", api); Loading Loading @@ -1186,9 +1190,9 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { mCore->freeAllBuffersLocked(); // Remove our death notification callback if we have one if (mCore->mConnectedProducerListener != NULL) { if (mCore->mLinkedToDeath != NULL) { sp<IBinder> token = IInterface::asBinder(mCore->mConnectedProducerListener); IInterface::asBinder(mCore->mLinkedToDeath); // This can fail if we're here because of the death // notification, but we just ignore it token->unlinkToDeath( Loading @@ -1196,6 +1200,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { } mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; mCore->mLinkedToDeath = NULL; mCore->mConnectedProducerListener = NULL; mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; mCore->mConnectedPid = -1; Loading libs/gui/IProducerListener.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ namespace android { enum { ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION, NEEDS_RELEASE_NOTIFY, }; class BpProducerListener : public BpInterface<IProducerListener> Loading @@ -37,6 +38,23 @@ public: data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY); } virtual bool needsReleaseNotify() { bool result; Parcel data, reply; data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); status_t err = remote()->transact(NEEDS_RELEASE_NOTIFY, data, &reply); if (err != NO_ERROR) { ALOGE("IProducerListener: binder call \'needsReleaseNotify\' failed"); return true; } err = reply.readBool(&result); if (err != NO_ERROR) { ALOGE("IProducerListener: malformed binder reply"); return true; } return result; } }; // Out-of-line virtual method definition to trigger vtable emission in this Loading @@ -52,8 +70,16 @@ status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, CHECK_INTERFACE(IProducerListener, data, reply); onBufferReleased(); return NO_ERROR; case NEEDS_RELEASE_NOTIFY: CHECK_INTERFACE(IProducerListener, data, reply); reply->writeBool(needsReleaseNotify()); return NO_ERROR; } return BBinder::onTransact(code, data, reply, flags); } bool BnProducerListener::needsReleaseNotify() { return true; } } // namespace android Loading
include/gui/BufferQueueCore.h +5 −1 Original line number Diff line number Diff line Loading @@ -185,8 +185,12 @@ private: // PID of the process which last successfully called connect(...) pid_t mConnectedPid; // mConnectedProducerToken is used to set a binder death notification on // mLinkedToDeath is used to set a binder death notification on // the producer. sp<IProducerListener> mLinkedToDeath; // mConnectedProducerListener is used to handle the onBufferReleased // notification. sp<IProducerListener> mConnectedProducerListener; // mSlots is an array of buffer slots that must be mirrored on the producer Loading
include/gui/IProducerListener.h +3 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ public: // This is called without any lock held and can be called concurrently by // multiple threads. virtual void onBufferReleased() = 0; // Asynchronous virtual bool needsReleaseNotify() = 0; }; class IProducerListener : public ProducerListener, public IInterface Loading @@ -54,12 +55,14 @@ class BnProducerListener : public BnInterface<IProducerListener> public: virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); virtual bool needsReleaseNotify(); }; class DummyProducerListener : public BnProducerListener { public: virtual void onBufferReleased() {} virtual bool needsReleaseNotify() { return false; } }; } // namespace android Loading
libs/gui/BufferQueueCore.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) : mConsumerListener(), mConsumerUsageBits(0), mConnectedApi(NO_CONNECTED_API), mLinkedToDeath(), mConnectedProducerListener(), mSlots(), mQueue(), Loading
libs/gui/BufferQueueProducer.cpp +17 −12 Original line number Diff line number Diff line Loading @@ -1113,18 +1113,22 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, static_cast<uint32_t>(mCore->mQueue.size()), mCore->mFrameCounter + 1); if (listener != NULL) { // Set up a death notification so that we can disconnect // automatically if the remote producer dies if (listener != NULL && IInterface::asBinder(listener)->remoteBinder() != NULL) { if (IInterface::asBinder(listener)->remoteBinder() != NULL) { status = IInterface::asBinder(listener)->linkToDeath( static_cast<IBinder::DeathRecipient*>(this)); if (status != NO_ERROR) { BQ_LOGE("connect: linkToDeath failed: %s (%d)", strerror(-status), status); } mCore->mLinkedToDeath = listener; } if (listener->needsReleaseNotify()) { mCore->mConnectedProducerListener = listener; } } break; default: BQ_LOGE("connect: unknown API %d", api); Loading Loading @@ -1186,9 +1190,9 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { mCore->freeAllBuffersLocked(); // Remove our death notification callback if we have one if (mCore->mConnectedProducerListener != NULL) { if (mCore->mLinkedToDeath != NULL) { sp<IBinder> token = IInterface::asBinder(mCore->mConnectedProducerListener); IInterface::asBinder(mCore->mLinkedToDeath); // This can fail if we're here because of the death // notification, but we just ignore it token->unlinkToDeath( Loading @@ -1196,6 +1200,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { } mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; mCore->mLinkedToDeath = NULL; mCore->mConnectedProducerListener = NULL; mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; mCore->mConnectedPid = -1; Loading
libs/gui/IProducerListener.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ namespace android { enum { ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION, NEEDS_RELEASE_NOTIFY, }; class BpProducerListener : public BpInterface<IProducerListener> Loading @@ -37,6 +38,23 @@ public: data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY); } virtual bool needsReleaseNotify() { bool result; Parcel data, reply; data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); status_t err = remote()->transact(NEEDS_RELEASE_NOTIFY, data, &reply); if (err != NO_ERROR) { ALOGE("IProducerListener: binder call \'needsReleaseNotify\' failed"); return true; } err = reply.readBool(&result); if (err != NO_ERROR) { ALOGE("IProducerListener: malformed binder reply"); return true; } return result; } }; // Out-of-line virtual method definition to trigger vtable emission in this Loading @@ -52,8 +70,16 @@ status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, CHECK_INTERFACE(IProducerListener, data, reply); onBufferReleased(); return NO_ERROR; case NEEDS_RELEASE_NOTIFY: CHECK_INTERFACE(IProducerListener, data, reply); reply->writeBool(needsReleaseNotify()); return NO_ERROR; } return BBinder::onTransact(code, data, reply, flags); } bool BnProducerListener::needsReleaseNotify() { return true; } } // namespace android