Return error when trying to disconnect twice
Bug: 34637488
Bug: 36737364
Test: cts-tradefed run cts-dev --module Graphics
Test: libgui_test
Change-Id: I9deb1e8978e3789269ed1cf9753892b68f246e0f
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 5810335..9250806 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -487,6 +487,7 @@
// is considered a no-op.
//
// Return of a value other than NO_ERROR means an error has occurred:
+ // * NO_INIT - the producer is not connected
// * BAD_VALUE - one of the following has occurred:
// * the api specified does not match the one that was connected
// * api was out of range (see above).
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index aef231a..f101e47 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1267,7 +1267,10 @@
mCore->mSidebandStream.clear();
mCore->mDequeueCondition.broadcast();
listener = mCore->mConsumerListener;
- } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+ } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("disconnect: not connected (req=%d)", api);
+ status = NO_INIT;
+ } else {
BQ_LOGE("disconnect: still connected to another API "
"(cur=%d req=%d)", mCore->mConnectedApi, api);
status = BAD_VALUE;
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 55e6fbf..510dd31 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -1181,4 +1181,21 @@
ASSERT_NE(nullptr, item.mGraphicBuffer.get());
}
+TEST_F(BufferQueueTest, TestProducerConnectDisconnect) {
+ createBufferQueue();
+ sp<DummyConsumer> dc(new DummyConsumer);
+ ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
+ IGraphicBufferProducer::QueueBufferOutput output;
+ sp<IProducerListener> dummyListener(new DummyProducerListener);
+ ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
+ ASSERT_EQ(OK, mProducer->connect(
+ dummyListener, NATIVE_WINDOW_API_CPU, true, &output));
+ ASSERT_EQ(BAD_VALUE, mProducer->connect(
+ dummyListener, NATIVE_WINDOW_API_MEDIA, true, &output));
+
+ ASSERT_EQ(BAD_VALUE, mProducer->disconnect(NATIVE_WINDOW_API_MEDIA));
+ ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
+ ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
+}
+
} // namespace android
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index 3fe7642..a1b3621 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -464,7 +464,9 @@
std::unique_lock<std::mutex> lock(core_->mutex_);
- if (api != core_->connected_api_) {
+ if (BufferHubQueueCore::kNoConnectedApi == core_->connected_api_) {
+ return NO_INIT;
+ } else if (api != core_->connected_api_) {
return BAD_VALUE;
}