summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Carr <racarr@google.com>2016-09-08 13:54:35 -0700
committerRobert Carr <racarr@google.com>2016-09-14 09:48:40 -0700
commit97b9c86338e2d364d47ea7522c2d81a8014f0e07 (patch)
tree263e7e5a01758911cf2ee61c926ebf85db3d5f27
parent669867835ba2a8120cc3c171c8dc3e41ae9b9c8c (diff)
downloadnative-97b9c86338e2d364d47ea7522c2d81a8014f0e07.tar.gz
Surface: Add force disconnection method.
Add a new method forceScopedDisconnect to Surface. This will be used by the framework to force disconnection at times where the underlying GraphicBufferProducer may be about to be reused. This is scoped by PID to avoid conflicting with remote producers. Bug: 30236166 Change-Id: I857216483c0b550f240b3baea41977cbc58a67ed
-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);