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 5#include "content/browser/android/content_readback_handler.h" 6 7#include "base/android/jni_android.h" 8#include "base/bind.h" 9#include "cc/output/copy_output_request.h" 10#include "cc/output/copy_output_result.h" 11#include "content/browser/android/content_view_core_impl.h" 12#include "jni/ContentReadbackHandler_jni.h" 13#include "third_party/skia/include/core/SkBitmap.h" 14#include "ui/base/android/window_android.h" 15#include "ui/base/android/window_android_compositor.h" 16#include "ui/gfx/android/java_bitmap.h" 17#include "ui/gfx/rect.h" 18 19namespace content { 20 21namespace { 22 23typedef base::Callback<void(bool, const SkBitmap&)> ResultCallback; 24 25void OnFinishCopyOutputRequest( 26 const ResultCallback& result_callback, 27 scoped_ptr<cc::CopyOutputResult> copy_output_result) { 28 if (!copy_output_result->HasBitmap()) { 29 result_callback.Run(false, SkBitmap()); 30 return; 31 } 32 33 scoped_ptr<SkBitmap> bitmap = copy_output_result->TakeBitmap(); 34 result_callback.Run(true, *bitmap.Pass()); 35} 36 37} // anonymous namespace 38 39// static 40bool ContentReadbackHandler::RegisterContentReadbackHandler(JNIEnv* env) { 41 return RegisterNativesImpl(env); 42} 43 44ContentReadbackHandler::ContentReadbackHandler(JNIEnv* env, jobject obj) 45 : weak_factory_(this) { 46 java_obj_.Reset(env, obj); 47} 48 49void ContentReadbackHandler::Destroy(JNIEnv* env, jobject obj) { 50 delete this; 51} 52 53void ContentReadbackHandler::GetContentBitmap(JNIEnv* env, 54 jobject obj, 55 jint readback_id, 56 jfloat scale, 57 jobject color_type, 58 jfloat x, 59 jfloat y, 60 jfloat width, 61 jfloat height, 62 jobject content_view_core) { 63 ContentViewCore* view = 64 ContentViewCore::GetNativeContentViewCore(env, content_view_core); 65 DCHECK(view); 66 67 ResultCallback result_callback = 68 base::Bind(&ContentReadbackHandler::OnFinishReadback, 69 weak_factory_.GetWeakPtr(), 70 readback_id); 71 72 SkColorType sk_color_type = gfx::ConvertToSkiaColorType(color_type); 73 view->GetScaledContentBitmap( 74 scale, sk_color_type, gfx::Rect(x, y, width, height), result_callback); 75} 76 77void ContentReadbackHandler::GetCompositorBitmap(JNIEnv* env, 78 jobject obj, 79 jint readback_id, 80 jlong native_window_android) { 81 ui::WindowAndroid* window_android = 82 reinterpret_cast<ui::WindowAndroid*>(native_window_android); 83 DCHECK(window_android); 84 85 ResultCallback result_callback = 86 base::Bind(&ContentReadbackHandler::OnFinishReadback, 87 weak_factory_.GetWeakPtr(), 88 readback_id); 89 90 base::Callback<void(scoped_ptr<cc::CopyOutputResult>)> copy_output_callback = 91 base::Bind(&OnFinishCopyOutputRequest, 92 result_callback); 93 94 ui::WindowAndroidCompositor* compositor = window_android->GetCompositor(); 95 96 if (!compositor) { 97 copy_output_callback.Run(cc::CopyOutputResult::CreateEmptyResult()); 98 return; 99 } 100 101 compositor->RequestCopyOfOutputOnRootLayer( 102 cc::CopyOutputRequest::CreateBitmapRequest(copy_output_callback)); 103} 104 105ContentReadbackHandler::~ContentReadbackHandler() {} 106 107void ContentReadbackHandler::OnFinishReadback(int readback_id, 108 bool success, 109 const SkBitmap& bitmap) { 110 JNIEnv* env = base::android::AttachCurrentThread(); 111 ScopedJavaLocalRef<jobject> java_bitmap; 112 if (success) 113 java_bitmap = gfx::ConvertToJavaBitmap(&bitmap); 114 115 Java_ContentReadbackHandler_notifyGetBitmapFinished( 116 env, java_obj_.obj(), readback_id, java_bitmap.obj()); 117} 118 119// static 120static jlong Init(JNIEnv* env, jobject obj) { 121 ContentReadbackHandler* content_readback_handler = 122 new ContentReadbackHandler(env, obj); 123 return reinterpret_cast<intptr_t>(content_readback_handler); 124} 125 126} // namespace content 127