ContentReadbackHandler.java revision 0de6073388f4e2780db8536178b129cd8f6ab386
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; 14 15/** 16 * A class for reading back content. 17 */ 18@JNINamespace("content") 19public abstract class ContentReadbackHandler { 20 /** 21 * A callback interface for content readback into a bitmap. 22 */ 23 public static interface GetContentBitmapCallback { 24 /** 25 * Called when the content readback finishes. 26 * @param success Indicates whether the readback succeeded or not. 27 * @param bitmap The {@link Bitmap} of the content. 28 */ 29 public void onFinishGetContentBitmap(boolean success, Bitmap bitmap); 30 } 31 32 private int mNextReadbackId = 1; 33 private SparseArray<GetContentBitmapCallback> mGetContentBitmapRequests; 34 35 private long mNativeContentReadbackHandler; 36 37 /** 38 * Creates a {@link ContentReadbackHandler}. 39 */ 40 public ContentReadbackHandler() { 41 mGetContentBitmapRequests = new SparseArray<GetContentBitmapCallback>(); 42 } 43 44 /** 45 * Initialize the native object. 46 */ 47 public void initNativeContentReadbackHandler() { 48 mNativeContentReadbackHandler = nativeInit(); 49 } 50 51 /** 52 * Should be called when the ContentReadackHandler is not needed anymore. 53 */ 54 public void destroy() { 55 nativeDestroy(mNativeContentReadbackHandler); 56 mNativeContentReadbackHandler = 0; 57 } 58 59 60 @CalledByNative 61 private void notifyGetContentBitmapFinished(int readbackId, boolean success, Bitmap bitmap) { 62 GetContentBitmapCallback callback = mGetContentBitmapRequests.get(readbackId); 63 if (callback != null) { 64 mGetContentBitmapRequests.delete(readbackId); 65 callback.onFinishGetContentBitmap(success, bitmap); 66 } else { 67 // readback Id is unregistered. 68 assert false : "Readback finished for unregistered Id: " + readbackId; 69 } 70 } 71 72 /** 73 * Asynchronously, generate and grab a bitmap representing what is currently on the screen 74 * for {@code view}. 75 * 76 * @param scale The scale that should be applied to the content. 77 * @param srcRect A subrect of the original content to capture. If this is empty, it will grab 78 * the whole surface. 79 * @param view The {@link ContentViewCore} to grab the bitmap from. 80 * @param callback The callback to be executed after readback completes. 81 */ 82 public void getContentBitmapAsync(float scale, Rect srcRect, ContentViewCore view, 83 GetContentBitmapCallback callback) { 84 if (!readyForReadback()) { 85 callback.onFinishGetContentBitmap(false, null); 86 return; 87 } 88 ThreadUtils.assertOnUiThread(); 89 90 int readbackId = mNextReadbackId++; 91 mGetContentBitmapRequests.put(readbackId, callback); 92 nativeGetContentBitmap(mNativeContentReadbackHandler, readbackId, scale, 93 Bitmap.Config.ARGB_8888, srcRect.top, srcRect.left, srcRect.width(), 94 srcRect.height(), view); 95 } 96 97 /** 98 * Implemented by the owner of this class to signal whether readback is possible or not. 99 * @return Whether readback is possible or not. 100 */ 101 protected abstract boolean readyForReadback(); 102 103 private native long nativeInit(); 104 private native void nativeDestroy(long nativeContentReadbackHandler); 105 private native void nativeGetContentBitmap(long nativeContentReadbackHandler, int readback_id, 106 float scale, Bitmap.Config config, float x, float y, float width, float height, 107 Object contentViewCore); 108} 109