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