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 "chrome/browser/favicon/favicon_service.h"
14#include "chrome/browser/favicon/favicon_service_factory.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/profiles/profile_android.h"
17#include "jni/FaviconHelper_jni.h"
18#include "third_party/skia/include/core/SkBitmap.h"
19#include "ui/gfx/android/java_bitmap.h"
20
21using base::android::ScopedJavaGlobalRef;
22using base::android::ScopedJavaLocalRef;
23using base::android::AttachCurrentThread;
24using base::android::ConvertJavaStringToUTF16;
25using base::android::ConvertUTF8ToJavaString;
26using base::android::MethodID;
27
28namespace {
29
30void FaviconImageCallback(
31    ScopedJavaGlobalRef<jobject>* java_favicon_image_callback,
32    const chrome::FaviconImageResult& favicon_image_result) {
33  JNIEnv* env = AttachCurrentThread();
34
35  // Convert favicon_image_result to java objects.
36  ScopedJavaLocalRef<jstring> java_icon_url = ConvertUTF8ToJavaString(
37      env, favicon_image_result.icon_url.spec());
38  SkBitmap favicon_bitmap = favicon_image_result.image.AsBitmap();
39  ScopedJavaLocalRef<jobject> java_favicon_bitmap;
40  if (!favicon_bitmap.isNull()) {
41    java_favicon_bitmap = gfx::ConvertToJavaBitmap(&favicon_bitmap);
42  }
43
44  // Call java side FaviconImageCallback method.
45  Java_FaviconImageCallback_onFaviconAvailable(
46      env, java_favicon_image_callback->obj(), java_favicon_bitmap.obj(),
47      java_icon_url.obj());
48}
49
50}  // namespace
51
52static jint Init(JNIEnv* env, jclass clazz) {
53  return reinterpret_cast<jint>(new FaviconHelper());
54}
55
56FaviconHelper::FaviconHelper() {
57  cancelable_task_tracker_.reset(new CancelableTaskTracker());
58}
59
60void FaviconHelper::Destroy(JNIEnv* env, jobject obj) {
61  delete this;
62}
63
64jboolean FaviconHelper::GetFaviconImageForURL(
65    JNIEnv* env, jobject obj, jobject jprofile, jstring page_url,
66    jint icon_types, jint desired_size_in_dip,
67    jobject java_favicon_image_callback) {
68  Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile);
69  DCHECK(profile);
70  if (!profile)
71    return false;
72
73  FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
74      profile, Profile::EXPLICIT_ACCESS);
75  DCHECK(favicon_service);
76  if (!favicon_service)
77    return false;
78
79  FaviconService::FaviconForURLParams params(
80      profile, GURL(ConvertJavaStringToUTF16(env, page_url)),
81      static_cast<int>(icon_types), static_cast<int>(desired_size_in_dip));
82
83  ScopedJavaGlobalRef<jobject>* j_scoped_favicon_callback =
84      new ScopedJavaGlobalRef<jobject>();
85  j_scoped_favicon_callback->Reset(env, java_favicon_image_callback);
86
87  FaviconService::FaviconImageCallback callback_runner = base::Bind(
88      &FaviconImageCallback, base::Owned(j_scoped_favicon_callback));
89
90  favicon_service->GetFaviconImageForURL(
91      params, callback_runner,
92      cancelable_task_tracker_.get());
93
94  return true;
95}
96
97FaviconHelper::~FaviconHelper() {
98}
99
100// static
101bool FaviconHelper::RegisterFaviconHelper(JNIEnv* env) {
102  return RegisterNativesImpl(env);
103}
104