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 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