diff options
Diffstat (limited to 'chromium/content/browser/android/content_readback_handler.cc')
-rw-r--r-- | chromium/content/browser/android/content_readback_handler.cc | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/chromium/content/browser/android/content_readback_handler.cc b/chromium/content/browser/android/content_readback_handler.cc new file mode 100644 index 00000000000..841ef5f051a --- /dev/null +++ b/chromium/content/browser/android/content_readback_handler.cc @@ -0,0 +1,125 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/android/content_readback_handler.h" + +#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); +} + +ContentReadbackHandler::ContentReadbackHandler(JNIEnv* env, jobject obj) + : weak_factory_(this) { + java_obj_.Reset(env, obj); +} + +void ContentReadbackHandler::Destroy(JNIEnv* env, jobject obj) { + delete this; +} + +void ContentReadbackHandler::GetContentBitmap(JNIEnv* env, + jobject obj, + jint readback_id, + jfloat scale, + jobject config, + jfloat x, + jfloat y, + jfloat width, + jfloat height, + jobject content_view_core) { + ContentViewCore* view = + ContentViewCore::GetNativeContentViewCore(env, content_view_core); + DCHECK(view); + + ResultCallback result_callback = + base::Bind(&ContentReadbackHandler::OnFinishReadback, + weak_factory_.GetWeakPtr(), + readback_id); + + view->GetScaledContentBitmap( + scale, config, gfx::Rect(x, y, width, height), result_callback); +} + +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 +static jlong Init(JNIEnv* env, jobject obj) { + ContentReadbackHandler* content_readback_handler = + new ContentReadbackHandler(env, obj); + return reinterpret_cast<intptr_t>(content_readback_handler); +} + +} // namespace content |