summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/android/content_readback_handler.cc83
-rw-r--r--content/browser/android/content_readback_handler.h14
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc4
-rw-r--r--content/browser/renderer_host/compositor_impl_android.h2
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ContentReadbackHandler.java44
-rw-r--r--content/public/browser/android/compositor.h5
-rw-r--r--ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java42
-rw-r--r--ui/android/java/src/org/chromium/ui/base/WindowAndroid.java9
-rw-r--r--ui/base/android/window_android.cc16
-rw-r--r--ui/base/android/window_android.h3
10 files changed, 110 insertions, 112 deletions
diff --git a/content/browser/android/content_readback_handler.cc b/content/browser/android/content_readback_handler.cc
index 432b230..841ef5f 100644
--- a/content/browser/android/content_readback_handler.cc
+++ b/content/browser/android/content_readback_handler.cc
@@ -6,14 +6,36 @@
#include "base/android/jni_android.h"
#include "base/bind.h"
+#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
#include "content/browser/android/content_view_core_impl.h"
#include "jni/ContentReadbackHandler_jni.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/android/window_android.h"
+#include "ui/base/android/window_android_compositor.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/rect.h"
namespace content {
+namespace {
+
+typedef base::Callback<void(bool, const SkBitmap&)> ResultCallback;
+
+void OnFinishCopyOutputRequest(
+ const ResultCallback& result_callback,
+ scoped_ptr<cc::CopyOutputResult> copy_output_result) {
+ if (!copy_output_result->HasBitmap()) {
+ result_callback.Run(false, SkBitmap());
+ return;
+ }
+
+ scoped_ptr<SkBitmap> bitmap = copy_output_result->TakeBitmap();
+ result_callback.Run(true, *bitmap.Pass());
+}
+
+} // anonymous namespace
+
// static
bool ContentReadbackHandler::RegisterContentReadbackHandler(JNIEnv* env) {
return RegisterNativesImpl(env);
@@ -24,24 +46,10 @@ ContentReadbackHandler::ContentReadbackHandler(JNIEnv* env, jobject obj)
java_obj_.Reset(env, obj);
}
-ContentReadbackHandler::~ContentReadbackHandler() {}
-
void ContentReadbackHandler::Destroy(JNIEnv* env, jobject obj) {
delete this;
}
-void ContentReadbackHandler::OnFinishContentReadback(int readback_id,
- bool success,
- const SkBitmap& bitmap) {
- JNIEnv* env = base::android::AttachCurrentThread();
- ScopedJavaLocalRef<jobject> java_bitmap;
- if (success)
- java_bitmap = gfx::ConvertToJavaBitmap(&bitmap);
-
- Java_ContentReadbackHandler_notifyGetContentBitmapFinished(
- env, java_obj_.obj(), readback_id, success, java_bitmap.obj());
-}
-
void ContentReadbackHandler::GetContentBitmap(JNIEnv* env,
jobject obj,
jint readback_id,
@@ -56,14 +64,55 @@ void ContentReadbackHandler::GetContentBitmap(JNIEnv* env,
ContentViewCore::GetNativeContentViewCore(env, content_view_core);
DCHECK(view);
- base::Callback<void(bool, const SkBitmap&)> result_callback =
- base::Bind(&ContentReadbackHandler::OnFinishContentReadback,
+ ResultCallback result_callback =
+ base::Bind(&ContentReadbackHandler::OnFinishReadback,
weak_factory_.GetWeakPtr(),
readback_id);
view->GetScaledContentBitmap(
scale, config, gfx::Rect(x, y, width, height), result_callback);
- return;
+}
+
+void ContentReadbackHandler::GetCompositorBitmap(JNIEnv* env,
+ jobject obj,
+ jint readback_id,
+ jlong native_window_android) {
+ ui::WindowAndroid* window_android =
+ reinterpret_cast<ui::WindowAndroid*>(native_window_android);
+ DCHECK(window_android);
+
+ ResultCallback result_callback =
+ base::Bind(&ContentReadbackHandler::OnFinishReadback,
+ weak_factory_.GetWeakPtr(),
+ readback_id);
+
+ base::Callback<void(scoped_ptr<cc::CopyOutputResult>)> copy_output_callback =
+ base::Bind(&OnFinishCopyOutputRequest,
+ result_callback);
+
+ ui::WindowAndroidCompositor* compositor = window_android->GetCompositor();
+
+ if (!compositor) {
+ copy_output_callback.Run(cc::CopyOutputResult::CreateEmptyResult());
+ return;
+ }
+
+ compositor->RequestCopyOfOutputOnRootLayer(
+ cc::CopyOutputRequest::CreateBitmapRequest(copy_output_callback));
+}
+
+ContentReadbackHandler::~ContentReadbackHandler() {}
+
+void ContentReadbackHandler::OnFinishReadback(int readback_id,
+ bool success,
+ const SkBitmap& bitmap) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> java_bitmap;
+ if (success)
+ java_bitmap = gfx::ConvertToJavaBitmap(&bitmap);
+
+ Java_ContentReadbackHandler_notifyGetBitmapFinished(
+ env, java_obj_.obj(), readback_id, success, java_bitmap.obj());
}
// static
diff --git a/content/browser/android/content_readback_handler.h b/content/browser/android/content_readback_handler.h
index 11d5aa3..403bdd0 100644
--- a/content/browser/android/content_readback_handler.h
+++ b/content/browser/android/content_readback_handler.h
@@ -13,6 +13,10 @@
class SkBitmap;
+namespace cc {
+class CopyOutputResult;
+}
+
namespace content {
// Native side of the ContentReadbackHandler.java, which issues content
@@ -35,13 +39,17 @@ class ContentReadbackHandler {
jfloat width,
jfloat height,
jobject content_view_core);
+ void GetCompositorBitmap(JNIEnv* env,
+ jobject obj,
+ jint readback_id,
+ jlong native_window_android);
private:
virtual ~ContentReadbackHandler();
- void OnFinishContentReadback(int readback_id,
- bool success,
- const SkBitmap& bitmap);
+ void OnFinishReadback(int readback_id,
+ bool success,
+ const SkBitmap& bitmap);
base::android::ScopedJavaGlobalRef<jobject> java_obj_;
base::WeakPtrFactory<ContentReadbackHandler> weak_factory_;
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 2deb358..5e01b73 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -438,10 +438,6 @@ void CompositorImpl::SetHasTransparentBackground(bool flag) {
host_->set_has_transparent_background(flag);
}
-bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
- return false;
-}
-
void CompositorImpl::SetNeedsComposite() {
if (!host_.get() || needs_composite_)
return;
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index 91de0ae..0f1e88f 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -63,8 +63,6 @@ class CONTENT_EXPORT CompositorImpl
virtual void setDeviceScaleFactor(float factor) OVERRIDE;
virtual void SetWindowBounds(const gfx::Size& size) OVERRIDE;
virtual void SetHasTransparentBackground(bool flag) OVERRIDE;
- virtual bool CompositeAndReadback(
- void *pixels, const gfx::Rect& rect) OVERRIDE;
virtual void SetNeedsComposite() OVERRIDE;
virtual cc::UIResourceId GenerateUIResource(const SkBitmap& bitmap,
bool is_transient) OVERRIDE;
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentReadbackHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentReadbackHandler.java
index aab9aaa..15226d5 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentReadbackHandler.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentReadbackHandler.java
@@ -11,6 +11,7 @@ import android.util.SparseArray;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.base.ThreadUtils;
+import org.chromium.ui.base.WindowAndroid;
/**
* A class for reading back content.
@@ -20,17 +21,17 @@ public abstract class ContentReadbackHandler {
/**
* A callback interface for content readback into a bitmap.
*/
- public static interface GetContentBitmapCallback {
+ public static interface GetBitmapCallback {
/**
* Called when the content readback finishes.
* @param success Indicates whether the readback succeeded or not.
* @param bitmap The {@link Bitmap} of the content.
*/
- public void onFinishGetContentBitmap(boolean success, Bitmap bitmap);
+ public void onFinishGetBitmap(boolean success, Bitmap bitmap);
}
private int mNextReadbackId = 1;
- private SparseArray<GetContentBitmapCallback> mGetContentBitmapRequests;
+ private SparseArray<GetBitmapCallback> mGetBitmapRequests;
private long mNativeContentReadbackHandler;
@@ -38,7 +39,7 @@ public abstract class ContentReadbackHandler {
* Creates a {@link ContentReadbackHandler}.
*/
public ContentReadbackHandler() {
- mGetContentBitmapRequests = new SparseArray<GetContentBitmapCallback>();
+ mGetBitmapRequests = new SparseArray<GetBitmapCallback>();
}
/**
@@ -58,11 +59,11 @@ public abstract class ContentReadbackHandler {
@CalledByNative
- private void notifyGetContentBitmapFinished(int readbackId, boolean success, Bitmap bitmap) {
- GetContentBitmapCallback callback = mGetContentBitmapRequests.get(readbackId);
+ private void notifyGetBitmapFinished(int readbackId, boolean success, Bitmap bitmap) {
+ GetBitmapCallback callback = mGetBitmapRequests.get(readbackId);
if (callback != null) {
- mGetContentBitmapRequests.delete(readbackId);
- callback.onFinishGetContentBitmap(success, bitmap);
+ mGetBitmapRequests.delete(readbackId);
+ callback.onFinishGetBitmap(success, bitmap);
} else {
// readback Id is unregistered.
assert false : "Readback finished for unregistered Id: " + readbackId;
@@ -80,21 +81,40 @@ public abstract class ContentReadbackHandler {
* @param callback The callback to be executed after readback completes.
*/
public void getContentBitmapAsync(float scale, Rect srcRect, ContentViewCore view,
- GetContentBitmapCallback callback) {
+ GetBitmapCallback callback) {
if (!readyForReadback()) {
- callback.onFinishGetContentBitmap(false, null);
+ callback.onFinishGetBitmap(false, null);
return;
}
ThreadUtils.assertOnUiThread();
int readbackId = mNextReadbackId++;
- mGetContentBitmapRequests.put(readbackId, callback);
+ mGetBitmapRequests.put(readbackId, callback);
nativeGetContentBitmap(mNativeContentReadbackHandler, readbackId, scale,
Bitmap.Config.ARGB_8888, srcRect.top, srcRect.left, srcRect.width(),
srcRect.height(), view);
}
/**
+ * Asynchronously, grab a bitmap of the current browser compositor root layer.
+ *
+ * @param windowAndroid The window that hosts the compositor.
+ * @param callback The callback to be executed after readback completes.
+ */
+ public void getCompositorBitmapAsync(WindowAndroid windowAndroid, GetBitmapCallback callback) {
+ if (!readyForReadback()) {
+ callback.onFinishGetBitmap(false, null);
+ return;
+ }
+ ThreadUtils.assertOnUiThread();
+
+ int readbackId = mNextReadbackId++;
+ mGetBitmapRequests.put(readbackId, callback);
+ nativeGetCompositorBitmap(mNativeContentReadbackHandler, readbackId,
+ windowAndroid.getNativePointer());
+ }
+
+ /**
* Implemented by the owner of this class to signal whether readback is possible or not.
* @return Whether readback is possible or not.
*/
@@ -105,4 +125,6 @@ public abstract class ContentReadbackHandler {
private native void nativeGetContentBitmap(long nativeContentReadbackHandler, int readback_id,
float scale, Bitmap.Config config, float x, float y, float width, float height,
Object contentViewCore);
+ private native void nativeGetCompositorBitmap(long nativeContentReadbackHandler,
+ int readback_id, long nativeWindowAndroid);
}
diff --git a/content/public/browser/android/compositor.h b/content/public/browser/android/compositor.h
index 236a90d..2d8126b 100644
--- a/content/public/browser/android/compositor.h
+++ b/content/public/browser/android/compositor.h
@@ -64,11 +64,6 @@ class CONTENT_EXPORT Compositor {
// Tells the view tree to assume a transparent background when rendering.
virtual void SetHasTransparentBackground(bool flag) = 0;
- // Attempts to composite and read back the result into the provided buffer.
- // The buffer must be at least window width * height * 4 (RGBA) bytes large.
- // The buffer is not modified if false is returned.
- virtual bool CompositeAndReadback(void *pixels, const gfx::Rect& rect) = 0;
-
// Request layout and draw. You only need to call this if you need to trigger
// Composite *without* having modified the layer tree.
virtual void SetNeedsComposite() = 0;
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
index 99c8c41..07f48dc 100644
--- a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
@@ -9,14 +9,7 @@ import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.View;
-import org.chromium.ui.UiUtils;
-
-import java.io.ByteArrayOutputStream;
import java.lang.ref.WeakReference;
/**
@@ -105,41 +98,6 @@ public class ActivityWindowAndroid extends WindowAndroid {
return new WeakReference<Activity>(mActivityRef.get());
}
- /**
- * Returns a PNG-encoded screenshot of the the window region at (|windowX|,
- * |windowY|) with the size |width| by |height| pixels.
- */
- @Override
- public byte[] grabSnapshot(int windowX, int windowY, int width, int height) {
- Activity activity = mActivityRef.get();
- if (activity == null) return null;
- try {
- // Take a screenshot of the root activity view. This generally includes UI
- // controls such as the URL bar and OS windows such as the status bar.
- View rootView = activity.findViewById(android.R.id.content).getRootView();
- Bitmap bitmap = UiUtils.generateScaledScreenshot(rootView, 0, Bitmap.Config.ARGB_8888);
- if (bitmap == null) return null;
-
- // Clip the result into the requested region.
- if (windowX > 0 || windowY > 0 || width != bitmap.getWidth() ||
- height != bitmap.getHeight()) {
- Rect clip = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
- clip.intersect(windowX, windowY, windowX + width, windowY + height);
- bitmap = Bitmap.createBitmap(
- bitmap, clip.left, clip.top, clip.width(), clip.height());
- }
-
- // Compress the result into a PNG.
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- if (!bitmap.compress(Bitmap.CompressFormat.PNG, 100, result)) return null;
- bitmap.recycle();
- return result.toByteArray();
- } catch (OutOfMemoryError e) {
- Log.e(TAG, "Out of memory while grabbing window snapshot.", e);
- return null;
- }
- }
-
private int generateNextRequestCode() {
int requestCode = REQUEST_CODE_PREFIX + mNextRequestCode;
mNextRequestCode = (mNextRequestCode + 1) % REQUEST_CODE_RANGE_SIZE;
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index 4a68dea..424b566 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -279,15 +279,6 @@ public class WindowAndroid {
return mNativeWindowAndroid;
}
- /**
- * Returns a PNG-encoded screenshot of the the window region at (|windowX|,
- * |windowY|) with the size |width| by |height| pixels.
- */
- @CalledByNative
- public byte[] grabSnapshot(int windowX, int windowY, int width, int height) {
- return null;
- }
-
private native long nativeInit(long vsyncPeriod);
private native void nativeOnVSync(long nativeWindowAndroid, long vsyncTimeMicros);
private native void nativeDestroy(long nativeWindowAndroid);
diff --git a/ui/base/android/window_android.cc b/ui/base/android/window_android.cc
index 3dd3e6e..e462550 100644
--- a/ui/base/android/window_android.cc
+++ b/ui/base/android/window_android.cc
@@ -41,22 +41,6 @@ WindowAndroid::~WindowAndroid() {
WindowAndroidObserver, observer_list_, OnWillDestroyWindow());
}
-bool WindowAndroid::GrabSnapshot(
- int content_x, int content_y, int width, int height,
- std::vector<unsigned char>* png_representation) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jbyteArray> result =
- Java_WindowAndroid_grabSnapshot(env, GetJavaObject().obj(),
- content_x + content_offset_.x(),
- content_y + content_offset_.y(),
- width, height);
- if (result.is_null())
- return false;
- base::android::JavaByteArrayToByteVector(
- env, result.obj(), png_representation);
- return true;
-}
-
void WindowAndroid::OnCompositingDidCommit() {
FOR_EACH_OBSERVER(WindowAndroidObserver,
observer_list_,
diff --git a/ui/base/android/window_android.h b/ui/base/android/window_android.h
index 7e39184..df8685d 100644
--- a/ui/base/android/window_android.h
+++ b/ui/base/android/window_android.h
@@ -36,9 +36,6 @@ class UI_BASE_EXPORT WindowAndroid {
content_offset_ = content_offset;
}
- bool GrabSnapshot(int content_x, int content_y, int width, int height,
- std::vector<unsigned char>* png_representation);
-
// Compositor callback relay.
void OnCompositingDidCommit();