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