Home | History | Annotate | Download | only in android
      1 // Copyright 2013 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 "chrome/browser/android/favicon_helper.h"
      6 
      7 #include <jni.h>
      8 
      9 #include "base/android/jni_android.h"
     10 #include "base/android/jni_string.h"
     11 #include "base/android/scoped_java_ref.h"
     12 #include "base/bind.h"
     13 #include "base/strings/string_util.h"
     14 #include "base/strings/utf_string_conversions.h"
     15 #include "chrome/browser/favicon/favicon_service.h"
     16 #include "chrome/browser/favicon/favicon_service_factory.h"
     17 #include "chrome/browser/profiles/profile.h"
     18 #include "chrome/browser/profiles/profile_android.h"
     19 #include "chrome/browser/sync/open_tabs_ui_delegate.h"
     20 #include "chrome/browser/sync/profile_sync_service.h"
     21 #include "chrome/browser/sync/profile_sync_service_factory.h"
     22 #include "chrome/browser/sync/profile_sync_service_factory.h"
     23 #include "jni/FaviconHelper_jni.h"
     24 #include "third_party/skia/include/core/SkBitmap.h"
     25 #include "ui/gfx/android/java_bitmap.h"
     26 #include "ui/gfx/color_analysis.h"
     27 #include "ui/gfx/color_utils.h"
     28 
     29 using base::android::ScopedJavaGlobalRef;
     30 using base::android::ScopedJavaLocalRef;
     31 using base::android::AttachCurrentThread;
     32 using base::android::ConvertJavaStringToUTF16;
     33 using base::android::ConvertJavaStringToUTF8;
     34 using base::android::ConvertUTF8ToJavaString;
     35 
     36 namespace {
     37 
     38 void OnLocalFaviconAvailable(
     39     ScopedJavaGlobalRef<jobject>* j_favicon_image_callback,
     40     const chrome::FaviconImageResult& favicon_image_result) {
     41   JNIEnv* env = AttachCurrentThread();
     42 
     43   // Convert favicon_image_result to java objects.
     44   ScopedJavaLocalRef<jstring> j_icon_url =
     45       ConvertUTF8ToJavaString(env, favicon_image_result.icon_url.spec());
     46   SkBitmap favicon_bitmap = favicon_image_result.image.AsBitmap();
     47   ScopedJavaLocalRef<jobject> j_favicon_bitmap;
     48   if (!favicon_bitmap.isNull())
     49     j_favicon_bitmap = gfx::ConvertToJavaBitmap(&favicon_bitmap);
     50 
     51   // Call java side OnLocalFaviconAvailable method.
     52   Java_FaviconImageCallback_onFaviconAvailable(env,
     53                                                j_favicon_image_callback->obj(),
     54                                                j_favicon_bitmap.obj(),
     55                                                j_icon_url.obj());
     56 }
     57 
     58 }  // namespace
     59 
     60 static jlong Init(JNIEnv* env, jclass clazz) {
     61   return reinterpret_cast<intptr_t>(new FaviconHelper());
     62 }
     63 
     64 FaviconHelper::FaviconHelper() {
     65   cancelable_task_tracker_.reset(new CancelableTaskTracker());
     66 }
     67 
     68 void FaviconHelper::Destroy(JNIEnv* env, jobject obj) {
     69   delete this;
     70 }
     71 
     72 jboolean FaviconHelper::GetLocalFaviconImageForURL(
     73     JNIEnv* env,
     74     jobject obj,
     75     jobject j_profile,
     76     jstring j_page_url,
     77     jint j_icon_types,
     78     jint j_desired_size_in_dip,
     79     jobject j_favicon_image_callback) {
     80   Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
     81   DCHECK(profile);
     82   if (!profile)
     83     return false;
     84 
     85   FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
     86       profile, Profile::EXPLICIT_ACCESS);
     87   DCHECK(favicon_service);
     88   if (!favicon_service)
     89     return false;
     90 
     91   FaviconService::FaviconForURLParams params(
     92       GURL(ConvertJavaStringToUTF16(env, j_page_url)),
     93       static_cast<int>(j_icon_types),
     94       static_cast<int>(j_desired_size_in_dip));
     95 
     96   ScopedJavaGlobalRef<jobject>* j_scoped_favicon_callback =
     97       new ScopedJavaGlobalRef<jobject>();
     98   j_scoped_favicon_callback->Reset(env, j_favicon_image_callback);
     99 
    100   FaviconService::FaviconImageCallback callback_runner = base::Bind(
    101       &OnLocalFaviconAvailable, base::Owned(j_scoped_favicon_callback));
    102 
    103   favicon_service->GetFaviconImageForURL(
    104       params, callback_runner,
    105       cancelable_task_tracker_.get());
    106 
    107   return true;
    108 }
    109 
    110 ScopedJavaLocalRef<jobject> FaviconHelper::GetSyncedFaviconImageForURL(
    111     JNIEnv* env,
    112     jobject obj,
    113     jobject jprofile,
    114     jstring j_page_url) {
    115   Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile);
    116   DCHECK(profile);
    117 
    118   std::string page_url = ConvertJavaStringToUTF8(env, j_page_url);
    119 
    120   ProfileSyncService* sync_service =
    121       ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
    122   DCHECK(sync_service);
    123 
    124   scoped_refptr<base::RefCountedMemory> favicon_png;
    125   browser_sync::OpenTabsUIDelegate* open_tabs =
    126       sync_service->GetOpenTabsUIDelegate();
    127   DCHECK(open_tabs);
    128 
    129   if (!open_tabs->GetSyncedFaviconForPageURL(page_url, &favicon_png))
    130     return ScopedJavaLocalRef<jobject>();
    131 
    132     // Convert favicon_image_result to java objects.
    133   gfx::Image favicon_image = gfx::Image::CreateFrom1xPNGBytes(
    134       favicon_png->front(), favicon_png->size());
    135   SkBitmap favicon_bitmap = favicon_image.AsBitmap();
    136 
    137   ScopedJavaLocalRef<jobject> j_favicon_bitmap;
    138   if (favicon_bitmap.isNull())
    139     return ScopedJavaLocalRef<jobject>();
    140 
    141   return gfx::ConvertToJavaBitmap(&favicon_bitmap);
    142 }
    143 
    144 jint FaviconHelper::GetDominantColorForBitmap(JNIEnv* env,
    145                                               jobject obj,
    146                                               jobject bitmap) {
    147   if (!bitmap)
    148     return 0;
    149 
    150   gfx::JavaBitmap bitmap_lock(bitmap);
    151   SkBitmap skbitmap = gfx::CreateSkBitmapFromJavaBitmap(bitmap_lock);
    152   skbitmap.setImmutable();
    153   scoped_refptr<base::RefCountedMemory> png_data =
    154       gfx::Image::CreateFrom1xBitmap(skbitmap).As1xPNGBytes();
    155   uint32_t max_brightness = 665;
    156   uint32_t min_darkness = 100;
    157   color_utils::GridSampler sampler;
    158   return color_utils::CalculateKMeanColorOfPNG(
    159       png_data, min_darkness, max_brightness, &sampler);
    160 }
    161 
    162 FaviconHelper::~FaviconHelper() {}
    163 
    164 // static
    165 bool FaviconHelper::RegisterFaviconHelper(JNIEnv* env) {
    166   return RegisterNativesImpl(env);
    167 }
    168