rework screenshot API and implementation

- SurfaceFlinger now supports to take a screenshot
  directly into an IGraphicBufferProducer

- reimplement the IMemoryHeap screenshot on top
  of the above

- reimplement LayerScreenshot such that its
  BufferQueue is directly used as the destination
  of the screenshot. LayerScreenshot is now a thin
  wrapper around Layer

Bug: 6940974

Change-Id: I69a2096b44b91acbb99eba16f83a9c78d94e0d10
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 72b6277..0a79ff7 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -115,7 +115,7 @@
         data.writeInt32(reqHeight);
         data.writeInt32(minLayerZ);
         data.writeInt32(maxLayerZ);
-        remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
+        remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_DEPRECATED, data, &reply);
         *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
         *width = reply.readInt32();
         *height = reply.readInt32();
@@ -123,6 +123,23 @@
         return reply.readInt32();
     }
 
+    virtual status_t captureScreen(const sp<IBinder>& display,
+            const sp<IGraphicBufferProducer>& producer,
+            uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeStrongBinder(display);
+        data.writeStrongBinder(producer->asBinder());
+        data.writeInt32(reqWidth);
+        data.writeInt32(reqHeight);
+        data.writeInt32(minLayerZ);
+        data.writeInt32(maxLayerZ);
+        remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
+        return reply.readInt32();
+    }
+
     virtual bool authenticateSurfaceTexture(
             const sp<IGraphicBufferProducer>& bufferProducer) const
     {
@@ -268,7 +285,7 @@
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             bootFinished();
         } break;
-        case CAPTURE_SCREEN: {
+        case CAPTURE_SCREEN_DEPRECATED: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> display = data.readStrongBinder();
             uint32_t reqWidth = data.readInt32();
@@ -286,6 +303,19 @@
             reply->writeInt32(f);
             reply->writeInt32(res);
         } break;
+        case CAPTURE_SCREEN: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> display = data.readStrongBinder();
+            sp<IGraphicBufferProducer> producer =
+                    interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
+            uint32_t reqWidth = data.readInt32();
+            uint32_t reqHeight = data.readInt32();
+            uint32_t minLayerZ = data.readInt32();
+            uint32_t maxLayerZ = data.readInt32();
+            status_t res = captureScreen(display, producer,
+                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            reply->writeInt32(res);
+        } break;
         case AUTHENTICATE_SURFACE: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IGraphicBufferProducer> bufferProducer =
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index e8e208f..edfa78a 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -606,6 +606,17 @@
 
 // ----------------------------------------------------------------------------
 
+status_t ScreenshotClient::capture(
+        const sp<IBinder>& display,
+        const sp<IGraphicBufferProducer>& producer,
+        uint32_t reqWidth, uint32_t reqHeight,
+        uint32_t minLayerZ, uint32_t maxLayerZ) {
+    sp<ISurfaceComposer> s(ComposerService::getComposerService());
+    if (s == NULL) return NO_INIT;
+    return s->captureScreen(display, producer,
+            reqWidth, reqHeight, minLayerZ, maxLayerZ);
+}
+
 ScreenshotClient::ScreenshotClient()
     : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
 }