1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.content.browser;
7 import android.graphics.Bitmap;
8 import android.graphics.Rect;
9 import android.util.SparseArray;
11 import org.chromium.base.CalledByNative;
12 import org.chromium.base.JNINamespace;
13 import org.chromium.base.ThreadUtils;
14 import org.chromium.ui.base.WindowAndroid;
17 * A class for reading back content.
19 @JNINamespace("content")
20 public abstract class ContentReadbackHandler {
22 * A callback interface for content readback into a bitmap.
24 public static interface GetBitmapCallback {
26 * Called when the content readback finishes.
27 * @param bitmap The {@link Bitmap} of the content. Null will be passed for readback
30 public void onFinishGetBitmap(Bitmap bitmap);
33 private int mNextReadbackId = 1;
34 private SparseArray<GetBitmapCallback> mGetBitmapRequests;
36 private long mNativeContentReadbackHandler;
39 * Creates a {@link ContentReadbackHandler}.
41 public ContentReadbackHandler() {
42 mGetBitmapRequests = new SparseArray<GetBitmapCallback>();
46 * Initialize the native object.
48 public void initNativeContentReadbackHandler() {
49 mNativeContentReadbackHandler = nativeInit();
53 * Should be called when the ContentReadackHandler is not needed anymore.
55 public void destroy() {
56 if (mNativeContentReadbackHandler != 0) nativeDestroy(mNativeContentReadbackHandler);
57 mNativeContentReadbackHandler = 0;
62 private void notifyGetBitmapFinished(int readbackId, Bitmap bitmap) {
63 GetBitmapCallback callback = mGetBitmapRequests.get(readbackId);
64 if (callback != null) {
65 mGetBitmapRequests.delete(readbackId);
66 callback.onFinishGetBitmap(bitmap);
68 // readback Id is unregistered.
69 assert false : "Readback finished for unregistered Id: " + readbackId;
74 * Asynchronously, generate and grab a bitmap representing what is currently on the screen
77 * @param scale The scale that should be applied to the content.
78 * @param srcRect A subrect of the original content to capture. If this is empty, it will grab
80 * @param view The {@link ContentViewCore} to grab the bitmap from.
81 * @param callback The callback to be executed after readback completes.
83 public void getContentBitmapAsync(float scale, Rect srcRect, ContentViewCore view,
84 GetBitmapCallback callback) {
85 if (!readyForReadback()) {
86 callback.onFinishGetBitmap(null);
89 ThreadUtils.assertOnUiThread();
91 int readbackId = mNextReadbackId++;
92 mGetBitmapRequests.put(readbackId, callback);
93 nativeGetContentBitmap(mNativeContentReadbackHandler, readbackId, scale,
94 Bitmap.Config.ARGB_8888, srcRect.top, srcRect.left, srcRect.width(),
95 srcRect.height(), view);
99 * Asynchronously, grab a bitmap of the current browser compositor root layer.
101 * @param windowAndroid The window that hosts the compositor.
102 * @param callback The callback to be executed after readback completes.
104 public void getCompositorBitmapAsync(WindowAndroid windowAndroid, GetBitmapCallback callback) {
105 if (!readyForReadback()) {
106 callback.onFinishGetBitmap(null);
109 ThreadUtils.assertOnUiThread();
111 int readbackId = mNextReadbackId++;
112 mGetBitmapRequests.put(readbackId, callback);
113 nativeGetCompositorBitmap(mNativeContentReadbackHandler, readbackId,
114 windowAndroid.getNativePointer());
118 * Implemented by the owner of this class to signal whether readback is possible or not.
119 * @return Whether readback is possible or not.
121 protected abstract boolean readyForReadback();
123 private native long nativeInit();
124 private native void nativeDestroy(long nativeContentReadbackHandler);
125 private native void nativeGetContentBitmap(long nativeContentReadbackHandler, int readback_id,
126 float scale, Bitmap.Config config, float x, float y, float width, float height,
127 Object contentViewCore);
128 private native void nativeGetCompositorBitmap(long nativeContentReadbackHandler,
129 int readback_id, long nativeWindowAndroid);