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 19 namespace content { 20 21 namespace { 22 23 typedef base::Callback<void(bool, const SkBitmap&)> ResultCallback; 24 25 void 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 40 bool ContentReadbackHandler::RegisterContentReadbackHandler(JNIEnv* env) { 41 return RegisterNativesImpl(env); 42 } 43 44 ContentReadbackHandler::ContentReadbackHandler(JNIEnv* env, jobject obj) 45 : weak_factory_(this) { 46 java_obj_.Reset(env, obj); 47 } 48 49 void ContentReadbackHandler::Destroy(JNIEnv* env, jobject obj) { 50 delete this; 51 } 52 53 void 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 77 void 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 105 ContentReadbackHandler::~ContentReadbackHandler() {} 106 107 void 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 120 static 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