SurfaceTexture: fix queues-to-composer

This change fixes the NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER query of
Surface and SurfaceTextureClient.  Surface now uses the inherited
SurfaceTextureClient implementation of this query.  SurfaceTextureClient
now queries SurfaceFlinger to determine whether buffers that are queued
to its ISurfaceTexture will be sent to SurfaceFlinger (as opposed to
some other process).

Change-Id: Iff187e72f30d454229f07f896b438198978270a8
This commit is contained in:
Jamie Gennis 2011-08-17 18:19:00 -07:00
parent 3cff0866a2
commit 582270d69d
10 changed files with 58 additions and 26 deletions

View File

@ -132,9 +132,10 @@ public:
virtual status_t turnElectronBeamOff(int32_t mode) = 0;
virtual status_t turnElectronBeamOn(int32_t mode) = 0;
/* verify that an ISurface was created by SurfaceFlinger.
/* verify that an ISurfaceTexture was created by SurfaceFlinger.
*/
virtual bool authenticateSurface(const sp<ISurface>& surface) const = 0;
virtual bool authenticateSurfaceTexture(
const sp<ISurfaceTexture>& surface) const = 0;
};
// ----------------------------------------------------------------------------

View File

@ -31,6 +31,8 @@
#include <ui/DisplayInfo.h>
#include <gui/ISurfaceTexture.h>
#include <utils/Log.h>
// ---------------------------------------------------------------------------
@ -166,35 +168,36 @@ public:
return reply.readInt32();
}
virtual bool authenticateSurface(const sp<ISurface>& surface) const
virtual bool authenticateSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture) const
{
Parcel data, reply;
int err = NO_ERROR;
err = data.writeInterfaceToken(
ISurfaceComposer::getInterfaceDescriptor());
if (err != NO_ERROR) {
LOGE("ISurfaceComposer::authenticateSurface: error writing "
LOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
"interface descriptor: %s (%d)", strerror(-err), -err);
return false;
}
err = data.writeStrongBinder(surface->asBinder());
err = data.writeStrongBinder(surfaceTexture->asBinder());
if (err != NO_ERROR) {
LOGE("ISurfaceComposer::authenticateSurface: error writing strong "
"binder to parcel: %s (%d)", strerror(-err), -err);
LOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
"strong binder to parcel: %s (%d)", strerror(-err), -err);
return false;
}
err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
&reply);
if (err != NO_ERROR) {
LOGE("ISurfaceComposer::authenticateSurface: error performing "
"transaction: %s (%d)", strerror(-err), -err);
LOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
"performing transaction: %s (%d)", strerror(-err), -err);
return false;
}
int32_t result = 0;
err = reply.readInt32(&result);
if (err != NO_ERROR) {
LOGE("ISurfaceComposer::authenticateSurface: error retrieving "
"result: %s (%d)", strerror(-err), -err);
LOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
"retrieving result: %s (%d)", strerror(-err), -err);
return false;
}
return result != 0;
@ -291,8 +294,9 @@ status_t BnSurfaceComposer::onTransact(
} break;
case AUTHENTICATE_SURFACE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
int32_t result = authenticateSurface(surface) ? 1 : 0;
sp<ISurfaceTexture> surfaceTexture =
interface_cast<ISurfaceTexture>(data.readStrongBinder());
int32_t result = authenticateSurfaceTexture(surfaceTexture) ? 1 : 0;
reply->writeInt32(result);
} break;
default:

View File

@ -342,9 +342,6 @@ sp<IBinder> Surface::asBinder() const {
int Surface::query(int what, int* value) const {
switch (what) {
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
*value = 1;
return NO_ERROR;
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_SURFACE;
return NO_ERROR;

View File

@ -18,6 +18,8 @@
//#define LOG_NDEBUG 0
#include <gui/SurfaceTextureClient.h>
#include <surfaceflinger/ISurfaceComposer.h>
#include <surfaceflinger/SurfaceComposerClient.h>
#include <utils/Log.h>
@ -234,7 +236,15 @@ int SurfaceTextureClient::query(int what, int* value) const {
}
break;
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
*value = 0;
{
sp<ISurfaceComposer> composer(
ComposerService::getComposerService());
if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
*value = 1;
} else {
*value = 0;
}
}
return NO_ERROR;
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;

View File

@ -133,6 +133,11 @@ sp<ISurface> Layer::createSurface()
return sur;
}
wp<IBinder> Layer::getSurfaceTextureBinder() const
{
return mSurfaceTexture->asBinder();
}
status_t Layer::setBuffers( uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags)
{

View File

@ -74,6 +74,9 @@ public:
virtual bool isProtected() const;
virtual void onRemoved();
// LayerBaseClient interface
virtual wp<IBinder> getSurfaceTextureBinder() const;
// only for debugging
inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; }

View File

@ -544,6 +544,10 @@ wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
return mClientSurfaceBinder;
}
wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const {
return 0;
}
void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
{
LayerBase::dump(result, buffer, SIZE);

View File

@ -288,6 +288,7 @@ public:
sp<ISurface> getSurface();
wp<IBinder> getSurfaceBinder() const;
virtual wp<IBinder> getSurfaceTextureBinder() const;
virtual sp<LayerBaseClient> getLayerBaseClient() const {
return const_cast<LayerBaseClient*>(this); }

View File

@ -353,9 +353,10 @@ void SurfaceFlinger::signalEvent() {
mEventQueue.invalidate();
}
bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const {
bool SurfaceFlinger::authenticateSurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture) const {
Mutex::Autolock _l(mStateLock);
sp<IBinder> surfBinder(surface->asBinder());
sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
// Check the visible layer list for the ISurface
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
@ -363,14 +364,17 @@ bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const {
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(currentLayers[i]);
sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
return true;
if (lbc != NULL) {
wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
if (lbcBinder == surfaceTextureBinder) {
return true;
}
}
}
// Check the layers in the purgatory. This check is here so that if a
// Surface gets destroyed before all the clients are done using it, the
// error will not be reported as "surface XYZ is not authenticated", but
// SurfaceTexture gets destroyed before all the clients are done using it,
// the error will not be reported as "surface XYZ is not authenticated", but
// will instead fail later on when the client tries to use the surface,
// which should be reported as "surface XYZ returned an -ENODEV". The
// purgatorized layers are no less authentic than the visible ones, so this
@ -379,8 +383,11 @@ bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const {
for (size_t i=0 ; i<purgatorySize ; i++) {
const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
return true;
if (lbc != NULL) {
wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
if (lbcBinder == surfaceTextureBinder) {
return true;
}
}
}

View File

@ -171,7 +171,7 @@ public:
virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags);
virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags);
virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
virtual bool authenticateSurface(const sp<ISurface>& surface) const;
virtual bool authenticateSurfaceTexture(const sp<ISurfaceTexture>& surface) const;
virtual status_t captureScreen(DisplayID dpy,
sp<IMemoryHeap>* heap,