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 config, 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 view->GetScaledContentBitmap( 73 scale, config, gfx::Rect(x, y, width, height), result_callback); 74 } 75 76 void ContentReadbackHandler::GetCompositorBitmap(JNIEnv* env, 77 jobject obj, 78 jint readback_id, 79 jlong native_window_android) { 80 ui::WindowAndroid* window_android = 81 reinterpret_cast<ui::WindowAndroid*>(native_window_android); 82 DCHECK(window_android); 83 84 ResultCallback result_callback = 85 base::Bind(&ContentReadbackHandler::OnFinishReadback, 86 weak_factory_.GetWeakPtr(), 87 readback_id); 88 89 base::Callback<void(scoped_ptr<cc::CopyOutputResult>)> copy_output_callback = 90 base::Bind(&OnFinishCopyOutputRequest, 91 result_callback); 92 93 ui::WindowAndroidCompositor* compositor = window_android->GetCompositor(); 94 95 if (!compositor) { 96 copy_output_callback.Run(cc::CopyOutputResult::CreateEmptyResult()); 97 return; 98 } 99 100 compositor->RequestCopyOfOutputOnRootLayer( 101 cc::CopyOutputRequest::CreateBitmapRequest(copy_output_callback)); 102 } 103 104 ContentReadbackHandler::~ContentReadbackHandler() {} 105 106 void ContentReadbackHandler::OnFinishReadback(int readback_id, 107 bool success, 108 const SkBitmap& bitmap) { 109 JNIEnv* env = base::android::AttachCurrentThread(); 110 ScopedJavaLocalRef<jobject> java_bitmap; 111 if (success) 112 java_bitmap = gfx::ConvertToJavaBitmap(&bitmap); 113 114 Java_ContentReadbackHandler_notifyGetBitmapFinished( 115 env, java_obj_.obj(), readback_id, success, java_bitmap.obj()); 116 } 117 118 // static 119 static jlong Init(JNIEnv* env, jobject obj) { 120 ContentReadbackHandler* content_readback_handler = 121 new ContentReadbackHandler(env, obj); 122 return reinterpret_cast<intptr_t>(content_readback_handler); 123 } 124 125 } // namespace content 126