summaryrefslogtreecommitdiff
path: root/libs/gui
diff options
context:
space:
mode:
author Matthew Bouyack <mbouyack@google.com> 2016-10-06 15:36:56 -0700
committer Matthew Bouyack <mbouyack@google.com> 2016-10-06 15:37:58 -0700
commit20e9085b51c00b7828e3a8fdfe902adc1c89a924 (patch)
tree66ece69b7161dc95e97872d4fa476143f77c79a4 /libs/gui
parent6f3e42399459f053cddda4fa2190f0ece3387e06 (diff)
parent3b8e6b2f30af0564538c2a660033d6a97ab8038f (diff)
resolve merge conflicts of 3b8e6b2 to nyc-mr1-dev-plus-aosp
Change-Id: I9c02a56d63de5828453aa8926ca801d96b04a6cf
Diffstat (limited to 'libs/gui')
-rw-r--r--libs/gui/BufferQueueCore.cpp1
-rw-r--r--libs/gui/BufferQueueProducer.cpp29
-rw-r--r--libs/gui/IProducerListener.cpp26
3 files changed, 44 insertions, 12 deletions
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index dccc4a93d5..d74d32c06d 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -62,6 +62,7 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
mConsumerListener(),
mConsumerUsageBits(0),
mConnectedApi(NO_CONNECTED_API),
+ mLinkedToDeath(),
mConnectedProducerListener(),
mSlots(),
mQueue(),
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index da60784591..f8f38725b5 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1114,18 +1114,22 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
static_cast<uint32_t>(mCore->mQueue.size()),
mCore->mFrameCounter + 1);
- // Set up a death notification so that we can disconnect
- // automatically if the remote producer dies
- if (listener != NULL &&
- 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);
+ if (listener != NULL) {
+ // Set up a death notification so that we can disconnect
+ // automatically if the remote producer dies
+ 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;
}
}
- mCore->mConnectedProducerListener = listener;
break;
default:
BQ_LOGE("connect: unknown API %d", api);
@@ -1187,9 +1191,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(
@@ -1197,6 +1201,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;
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index 855a4885cf..62abfa81c4 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -22,6 +22,7 @@ namespace android {
enum {
ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
+ NEEDS_RELEASE_NOTIFY,
};
class BpProducerListener : public BpInterface<IProducerListener>
@@ -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
@@ -52,6 +70,10 @@ 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);
}
@@ -60,4 +82,8 @@ ProducerListener::~ProducerListener() = default;
DummyProducerListener::~DummyProducerListener() = default;
+bool BnProducerListener::needsReleaseNotify() {
+ return true;
+}
+
} // namespace android