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