From abe815dd6978b718c04f6e22e1a893d2b51d11a1 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 19 Mar 2013 22:22:21 -0700 Subject: rework how we take screenshots for a CPU consumer We're not using IMemoryHeap as a transport anymore, instead we're providing a CpuConsumer and use the IGraphicBufferProducer version of the screenshot API. However, some GPU drivers don't support properly a GPU to CPU path, to work around this, we use a temporary BufferQueue on the server side for the GL rendering, and we use glReadPixels into the CpuConsumer (we're now using a CPU to CPU path which is always supported). Currently this "wrapping" is always performed, but it can be bypassed on devices that support the GPU to CPU path. This also addresses a DoS attack vector on SurfaceFlinger, where an application could consume all of SF's filedescriptors by creating a lot of screenshots in a row. Bug: 8390553 Change-Id: I9e81514c2a7711b9bb393f74305be7d2abe08f1c --- libs/gui/ISurfaceComposer.cpp | 47 ++++++------------------------------------- 1 file changed, 6 insertions(+), 41 deletions(-) (limited to 'libs/gui/ISurfaceComposer.cpp') diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 0a79ff763f..6442a8600d 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -102,31 +102,11 @@ public: remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); } - virtual status_t captureScreen( - const sp& display, sp* heap, - uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ) - { - Parcel data, reply; - data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - data.writeStrongBinder(display); - data.writeInt32(reqWidth); - data.writeInt32(reqHeight); - data.writeInt32(minLayerZ); - data.writeInt32(maxLayerZ); - remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_DEPRECATED, data, &reply); - *heap = interface_cast(reply.readStrongBinder()); - *width = reply.readInt32(); - *height = reply.readInt32(); - *format = reply.readInt32(); - return reply.readInt32(); - } - virtual status_t captureScreen(const sp& display, const sp& producer, uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ) + uint32_t minLayerZ, uint32_t maxLayerZ, + bool isCpuConsumer) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); @@ -136,6 +116,7 @@ public: data.writeInt32(reqHeight); data.writeInt32(minLayerZ); data.writeInt32(maxLayerZ); + data.writeInt32(isCpuConsumer); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); return reply.readInt32(); } @@ -285,24 +266,6 @@ status_t BnSurfaceComposer::onTransact( CHECK_INTERFACE(ISurfaceComposer, data, reply); bootFinished(); } break; - case CAPTURE_SCREEN_DEPRECATED: { - CHECK_INTERFACE(ISurfaceComposer, data, reply); - sp display = data.readStrongBinder(); - uint32_t reqWidth = data.readInt32(); - uint32_t reqHeight = data.readInt32(); - uint32_t minLayerZ = data.readInt32(); - uint32_t maxLayerZ = data.readInt32(); - sp heap; - uint32_t w, h; - PixelFormat f; - status_t res = captureScreen(display, &heap, &w, &h, &f, - reqWidth, reqHeight, minLayerZ, maxLayerZ); - reply->writeStrongBinder(heap->asBinder()); - reply->writeInt32(w); - reply->writeInt32(h); - reply->writeInt32(f); - reply->writeInt32(res); - } break; case CAPTURE_SCREEN: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp display = data.readStrongBinder(); @@ -312,8 +275,10 @@ status_t BnSurfaceComposer::onTransact( uint32_t reqHeight = data.readInt32(); uint32_t minLayerZ = data.readInt32(); uint32_t maxLayerZ = data.readInt32(); + bool isCpuConsumer = data.readInt32(); status_t res = captureScreen(display, producer, - reqWidth, reqHeight, minLayerZ, maxLayerZ); + reqWidth, reqHeight, minLayerZ, maxLayerZ, + isCpuConsumer); reply->writeInt32(res); } break; case AUTHENTICATE_SURFACE: { -- cgit v1.2.3