Home | History | Annotate | Download | only in android
      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