summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Carr <racarr@google.com>2016-09-22 21:17:40 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-09-22 21:17:40 +0000
commit6cc1933af9c0cf656f9a511155f6613f8dbba667 (patch)
tree4d57fdfa9778f946444837610eacad960d5633dc
parent993de79607f5bef0f92004f1ed8a388eda9078bc (diff)
parent97b9c86338e2d364d47ea7522c2d81a8014f0e07 (diff)
downloadnative-6cc1933af9c0cf656f9a511155f6613f8dbba667.tar.gz
Merge "Surface: Add force disconnection method." into nyc-mr1-dev
-rw-r--r--include/gui/BufferQueueCore.h2
-rw-r--r--include/gui/BufferQueueProducer.h11
-rw-r--r--include/gui/IGraphicBufferProducer.h15
-rw-r--r--include/gui/Surface.h5
-rw-r--r--libs/gui/BufferQueueProducer.cpp14
-rw-r--r--libs/gui/IGraphicBufferProducer.cpp6
-rw-r--r--libs/gui/Surface.cpp4
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp4
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h2
-rw-r--r--services/surfaceflinger/MonitoredProducer.cpp4
-rw-r--r--services/surfaceflinger/MonitoredProducer.h2
11 files changed, 43 insertions, 26 deletions
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index 82bc121af3..cc5c536d13 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -182,6 +182,8 @@ private:
// to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated
// by the connect and disconnect methods.
int mConnectedApi;
+ // PID of the process which last successfully called connect(...)
+ pid_t mConnectedPid;
// mConnectedProducerToken is used to set a binder death notification on
// the producer.
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index 838632c26d..8f613ee17d 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -135,15 +135,8 @@ public:
virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output);
- // disconnect attempts to disconnect a producer API from the BufferQueue.
- // Calling this method will cause any subsequent calls to other
- // 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);
+ // See IGraphicBufferProducer::disconnect
+ virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api);
// Attaches a sideband buffer stream to the IGraphicBufferProducer.
//
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index c62bc5899c..bf427fe4b9 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -458,17 +458,24 @@ public:
virtual status_t connect(const sp<IProducerListener>& listener,
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
// IGraphicBufferProducer. Calling this method will cause any subsequent
// calls to other 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 IGraphicBufferProducer is not currently
- // connected to the specified client API.
- //
// 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
// is considered a no-op.
//
@@ -477,7 +484,7 @@ public:
// * the api specified does not match the one that was connected
// * api was out of range (see above).
// * 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.
//
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 8177ec66af..f4a22cb733 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -203,7 +203,6 @@ protected:
virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);
virtual int connect(int api);
- virtual int disconnect(int api);
virtual int setBufferCount(int bufferCount);
virtual int setBuffersDimensions(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);
public:
+ virtual int disconnect(int api,
+ IGraphicBufferProducer::DisconnectMode mode =
+ IGraphicBufferProducer::DisconnectMode::Api);
+
virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers);
virtual int setAsyncMode(bool async);
virtual int setSharedBufferMode(bool sharedBufferMode);
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 47ab6f2fab..48b1db8f59 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -28,6 +28,7 @@
#define EGL_EGLEXT_PROTOTYPES
+#include <binder/IPCThreadState.h>
#include <gui/BufferItem.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
@@ -1130,7 +1131,7 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
status = BAD_VALUE;
break;
}
-
+ mCore->mConnectedPid = IPCThreadState::self()->getCallingPid();
mCore->mBufferHasBeenQueued = false;
mCore->mDequeueBufferCannotBlock = false;
if (mDequeueTimeout < 0) {
@@ -1143,7 +1144,7 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
return status;
}
-status_t BufferQueueProducer::disconnect(int api) {
+status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
ATRACE_CALL();
BQ_LOGV("disconnect: api %d", api);
@@ -1151,6 +1152,14 @@ status_t BufferQueueProducer::disconnect(int api) {
sp<IConsumerListener> listener;
{ // Autolock scope
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();
if (mCore->mIsAbandoned) {
@@ -1189,6 +1198,7 @@ status_t BufferQueueProducer::disconnect(int api) {
BufferQueueCore::INVALID_BUFFER_SLOT;
mCore->mConnectedProducerListener = NULL;
mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
+ mCore->mConnectedPid = -1;
mCore->mSidebandStream.clear();
mCore->mDequeueCondition.broadcast();
listener = mCore->mConsumerListener;
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index fbd704d03d..f4ba3bf15f 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -270,10 +270,11 @@ public:
return result;
}
- virtual status_t disconnect(int api) {
+ virtual status_t disconnect(int api, DisconnectMode mode) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
data.writeInt32(api);
+ data.writeInt32(static_cast<int32_t>(mode));
status_t result =remote()->transact(DISCONNECT, data, &reply);
if (result != NO_ERROR) {
return result;
@@ -621,7 +622,8 @@ status_t BnGraphicBufferProducer::onTransact(
case DISCONNECT: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
int api = data.readInt32();
- status_t res = disconnect(api);
+ DisconnectMode mode = static_cast<DisconnectMode>(data.readInt32());
+ status_t res = disconnect(api, mode);
reply->writeInt32(res);
return NO_ERROR;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index ab223ffd4b..08382908ba 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -844,14 +844,14 @@ int Surface::connect(int api, const sp<IProducerListener>& listener) {
}
-int Surface::disconnect(int api) {
+int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
ATRACE_CALL();
ALOGV("Surface::disconnect");
Mutex::Autolock lock(mMutex);
mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
mSharedBufferHasBeenQueued = false;
freeAllBuffers();
- int err = mGraphicBufferProducer->disconnect(api);
+ int err = mGraphicBufferProducer->disconnect(api, mode);
if (!err) {
mReqFormat = 0;
mReqWidth = 0;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 61bb0bd8d9..2190466ad9 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -563,8 +563,8 @@ status_t VirtualDisplaySurface::connect(const sp<IProducerListener>& listener,
return result;
}
-status_t VirtualDisplaySurface::disconnect(int api) {
- return mSource[SOURCE_SINK]->disconnect(api);
+status_t VirtualDisplaySurface::disconnect(int api, DisconnectMode mode) {
+ return mSource[SOURCE_SINK]->disconnect(api, mode);
}
status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stream*/) {
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index bf9b39c50d..70f717f8c2 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -115,7 +115,7 @@ private:
virtual int query(int what, int* value);
virtual status_t connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput* output);
- virtual status_t disconnect(int api);
+ virtual status_t disconnect(int api, DisconnectMode mode);
virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
virtual void allocateBuffers(uint32_t width, uint32_t height,
PixelFormat format, uint32_t usage);
diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index 36cfa3718a..ffaee7a107 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -102,8 +102,8 @@ status_t MonitoredProducer::connect(const sp<IProducerListener>& listener,
return mProducer->connect(listener, api, producerControlledByApp, output);
}
-status_t MonitoredProducer::disconnect(int api) {
- return mProducer->disconnect(api);
+status_t MonitoredProducer::disconnect(int api, DisconnectMode mode) {
+ return mProducer->disconnect(api, mode);
}
status_t MonitoredProducer::setSidebandStream(const sp<NativeHandle>& stream) {
diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h
index f64fe51ef5..66f6cf0bdb 100644
--- a/services/surfaceflinger/MonitoredProducer.h
+++ b/services/surfaceflinger/MonitoredProducer.h
@@ -50,7 +50,7 @@ public:
virtual int query(int what, int* value);
virtual status_t connect(const sp<IProducerListener>& token, int api,
bool producerControlledByApp, QueueBufferOutput* output);
- virtual status_t disconnect(int api);
+ virtual status_t disconnect(int api, DisconnectMode mode);
virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
virtual void allocateBuffers(uint32_t width, uint32_t height,
PixelFormat format, uint32_t usage);