API tweaks to PixelCopy and make it public

Bug: 27708453
Change-Id: I81667ce42f9ca1c1a13e1e61299927900845fc84
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 4a32589..49596e1 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -30,7 +30,7 @@
 namespace android {
 namespace uirenderer {
 
-bool Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
+CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
         Surface& surface, SkBitmap* bitmap) {
     // TODO: Clean this up and unify it with LayerRenderer::copyLayer,
     // of which most of this is copied from.
@@ -44,12 +44,12 @@
                 || destHeight > caches.maxTextureSize) {
         ALOGW("Can't copy surface into bitmap, %dx%d exceeds max texture size %d",
                 destWidth, destHeight, caches.maxTextureSize);
-        return false;
+        return CopyResult::DestinationInvalid;
     }
     GLuint fbo = renderState.createFramebuffer();
     if (!fbo) {
         ALOGW("Could not obtain an FBO");
-        return false;
+        return CopyResult::UnknownError;
     }
 
     SkAutoLockPixels alp(*bitmap);
@@ -104,16 +104,20 @@
     status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence);
     if (err != NO_ERROR) {
         ALOGW("Failed to get last queued buffer, error = %d", err);
-        return false;
+        return CopyResult::UnknownError;
     }
     if (!sourceBuffer.get()) {
         ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
-        return false;
+        return CopyResult::SourceEmpty;
+    }
+    if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) {
+        ALOGW("Surface is protected, unable to copy from it");
+        return CopyResult::SourceInvalid;
     }
     err = sourceFence->wait(500 /* ms */);
     if (err != NO_ERROR) {
         ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
-        return false;
+        return CopyResult::Timeout;
     }
 
     // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
@@ -130,7 +134,7 @@
 
     if (sourceImage == EGL_NO_IMAGE_KHR) {
         ALOGW("Error creating image (%#x)", eglGetError());
-        return false;
+        return CopyResult::UnknownError;
     }
     GLuint sourceTexId;
     // Create a 2D texture to sample from the EGLImage
@@ -141,7 +145,7 @@
     GLenum status = GL_NO_ERROR;
     while ((status = glGetError()) != GL_NO_ERROR) {
         ALOGW("Error creating image (%#x)", status);
-        return false;
+        return CopyResult::UnknownError;
     }
 
     Texture sourceTexture(caches);
@@ -178,7 +182,7 @@
 
     GL_CHECKPOINT(MODERATE);
 
-    return true;
+    return CopyResult::Success;
 }
 
 } // namespace uirenderer
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index ea03c82..a112c42 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -24,9 +24,19 @@
 namespace android {
 namespace uirenderer {
 
+// Keep in sync with PixelCopy.java codes
+enum class CopyResult {
+    Success = 0,
+    UnknownError = 1,
+    Timeout = 2,
+    SourceEmpty = 3,
+    SourceInvalid = 4,
+    DestinationInvalid = 5,
+};
+
 class Readback {
 public:
-    static bool copySurfaceInto(renderthread::RenderThread& renderThread,
+    static CopyResult copySurfaceInto(renderthread::RenderThread& renderThread,
             Surface& surface, SkBitmap* bitmap);
 };
 
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 5e37856..54af282 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -623,12 +623,13 @@
             *args->surface, args->bitmap);
 }
 
-bool RenderProxy::copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap) {
+int RenderProxy::copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap) {
     SETUP_TASK(copySurfaceInto);
     args->bitmap = bitmap;
     args->surface = surface.get();
     args->thread = &RenderThread::getInstance();
-    return (bool) staticPostAndWait(task);
+    return static_cast<int>(
+            reinterpret_cast<intptr_t>( staticPostAndWait(task) ));
 }
 
 void RenderProxy::post(RenderTask* task) {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index c39319d..898b314 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -127,7 +127,7 @@
     ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer);
     ANDROID_API long getDroppedFrameReportCount();
 
-    ANDROID_API static bool copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap);
+    ANDROID_API static int copySurfaceInto(sp<Surface>& surface, SkBitmap* bitmap);
 
 private:
     RenderThread& mRenderThread;