ContentReadbackHandler.java revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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. 4 5package org.chromium.content.browser; 6 7import android.graphics.Bitmap; 8import android.graphics.Rect; 9import android.util.SparseArray; 10 11import org.chromium.base.CalledByNative; 12import org.chromium.base.JNINamespace; 13import org.chromium.base.ThreadUtils; 14import org.chromium.ui.base.WindowAndroid; 15 16/** 17 * A class for reading back content. 18 */ 19@JNINamespace("content") 20public abstract class ContentReadbackHandler { 21 /** 22 * A callback interface for content readback into a bitmap. 23 */ 24 public static interface GetBitmapCallback { 25 /** 26 * Called when the content readback finishes. 27 * @param success Indicates whether the readback succeeded or not. 28 * @param bitmap The {@link Bitmap} of the content. 29 */ 30 public void onFinishGetBitmap(boolean success, Bitmap bitmap); 31 } 32 33 private int mNextReadbackId = 1; 34 private SparseArray<GetBitmapCallback> mGetBitmapRequests; 35 36 private long mNativeContentReadbackHandler; 37 38 /** 39 * Creates a {@link ContentReadbackHandler}. 40 */ 41 public ContentReadbackHandler() { 42 mGetBitmapRequests = new SparseArray<GetBitmapCallback>(); 43 } 44 45 /** 46 * Initialize the native object. 47 */ 48 public void initNativeContentReadbackHandler() { 49 mNativeContentReadbackHandler = nativeInit(); 50 } 51 52 /** 53 * Should be called when the ContentReadackHandler is not needed anymore. 54 */ 55 public void destroy() { 56 if (mNativeContentReadbackHandler != 0) nativeDestroy(mNativeContentReadbackHandler); 57 mNativeContentReadbackHandler = 0; 58 } 59 60 61 @CalledByNative 62 private void notifyGetBitmapFinished(int readbackId, boolean success, Bitmap bitmap) { 63 GetBitmapCallback callback = mGetBitmapRequests.get(readbackId); 64 if (callback != null) { 65 mGetBitmapRequests.delete(readbackId); 66 callback.onFinishGetBitmap(success, bitmap); 67 } else { 68 // readback Id is unregistered. 69 assert false : "Readback finished for unregistered Id: " + readbackId; 70 } 71 } 72 73 /** 74 * Asynchronously, generate and grab a bitmap representing what is currently on the screen 75 * for {@code view}. 76 * 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 79 * the whole surface. 80 * @param view The {@link ContentViewCore} to grab the bitmap from. 81 * @param callback The callback to be executed after readback completes. 82 */ 83 public void getContentBitmapAsync(float scale, Rect srcRect, ContentViewCore view, 84 GetBitmapCallback callback) { 85 if (!readyForReadback()) { 86 callback.onFinishGetBitmap(false, null); 87 return; 88 } 89 ThreadUtils.assertOnUiThread(); 90 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); 96 } 97 98 /** 99 * Asynchronously, grab a bitmap of the current browser compositor root layer. 100 * 101 * @param windowAndroid The window that hosts the compositor. 102 * @param callback The callback to be executed after readback completes. 103 */ 104 public void getCompositorBitmapAsync(WindowAndroid windowAndroid, GetBitmapCallback callback) { 105 if (!readyForReadback()) { 106 callback.onFinishGetBitmap(false, null); 107 return; 108 } 109 ThreadUtils.assertOnUiThread(); 110 111 int readbackId = mNextReadbackId++; 112 mGetBitmapRequests.put(readbackId, callback); 113 nativeGetCompositorBitmap(mNativeContentReadbackHandler, readbackId, 114 windowAndroid.getNativePointer()); 115 } 116 117 /** 118 * Implemented by the owner of this class to signal whether readback is possible or not. 119 * @return Whether readback is possible or not. 120 */ 121 protected abstract boolean readyForReadback(); 122 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); 130} 131