favicon_helper.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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
29using base::android::ScopedJavaGlobalRef;
30using base::android::ScopedJavaLocalRef;
31using base::android::AttachCurrentThread;
32using base::android::ConvertJavaStringToUTF16;
33using base::android::ConvertJavaStringToUTF8;
34using base::android::ConvertUTF8ToJavaString;
35
36namespace {
37
38void OnLocalFaviconAvailable(
39    ScopedJavaGlobalRef<jobject>* j_favicon_image_callback,
40    const favicon_base::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
60static jlong Init(JNIEnv* env, jclass clazz) {
61  return reinterpret_cast<intptr_t>(new FaviconHelper());
62}
63
64FaviconHelper::FaviconHelper() {
65  cancelable_task_tracker_.reset(new base::CancelableTaskTracker());
66}
67
68void FaviconHelper::Destroy(JNIEnv* env, jobject obj) {
69  delete this;
70}
71
72jboolean 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
110ScopedJavaLocalRef<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(favicon_png);
134  SkBitmap favicon_bitmap = favicon_image.AsBitmap();
135
136  ScopedJavaLocalRef<jobject> j_favicon_bitmap;
137  if (favicon_bitmap.isNull())
138    return ScopedJavaLocalRef<jobject>();
139
140  return gfx::ConvertToJavaBitmap(&favicon_bitmap);
141}
142
143FaviconHelper::~FaviconHelper() {}
144
145static jint GetDominantColorForBitmap(JNIEnv* env,
146                                      jclass clazz,
147                                      jobject bitmap) {
148  if (!bitmap)
149    return 0;
150
151    gfx::JavaBitmap bitmap_lock(bitmap);
152    SkBitmap skbitmap = gfx::CreateSkBitmapFromJavaBitmap(bitmap_lock);
153    return color_utils::CalculateKMeanColorOfBitmap(skbitmap);
154}
155
156// static
157bool FaviconHelper::RegisterFaviconHelper(JNIEnv* env) {
158  return RegisterNativesImpl(env);
159}
160