blob: 79ca5c86de0748aef3eb88b75cffaaf7e4e5e234 [file] [log] [blame]
[email protected]c764b2822013-07-03 04:16:481// 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/most_visited_sites.h"
6
7#include "base/android/jni_android.h"
8#include "base/android/jni_array.h"
9#include "base/android/jni_string.h"
10#include "base/android/scoped_java_ref.h"
11#include "chrome/browser/history/history_types.h"
12#include "chrome/browser/history/top_sites.h"
13#include "chrome/browser/profiles/profile.h"
14#include "chrome/browser/profiles/profile_android.h"
15#include "content/public/browser/browser_thread.h"
16#include "jni/MostVisitedSites_jni.h"
17#include "third_party/skia/include/core/SkBitmap.h"
18#include "ui/gfx/android/java_bitmap.h"
19#include "ui/gfx/codec/jpeg_codec.h"
20
21using base::android::AttachCurrentThread;
22using base::android::ConvertUTF8ToJavaString;
23using base::android::ConvertJavaStringToUTF8;
24using base::android::ScopedJavaGlobalRef;
25using base::android::ToJavaArrayOfStrings;
26using base::android::CheckException;
27using content::BrowserThread;
28using history::TopSites;
29
30namespace chrome {
31namespace android {
32
33bool RegisterMostVisitedSites(JNIEnv* env) {
34 return RegisterNativesImpl(env);
35}
36
37} // namespace android
38} // namespace chrome
39
40namespace {
41
42class NativeCallback : public base::RefCounted<NativeCallback> {
43 public:
44 NativeCallback(jobject j_callback_obj, int num_results)
45 : num_results_(num_results) {
46 JNIEnv* env = AttachCurrentThread();
47 j_callback_obj_.Reset(env, j_callback_obj);
48 }
49
50 void OnMostVisitedURLsAvailable(
51 const history::MostVisitedURLList& visited_list) {
52 std::vector<string16> titles;
53 std::vector<std::string> urls;
54 ExtractMostVisitedTitlesAndURLs(visited_list, &titles, &urls);
55
56 JNIEnv* env = AttachCurrentThread();
57 Java_MostVisitedURLsCallback_onMostVisitedURLsAvailable(
58 env,
59 j_callback_obj_.obj(),
60 ToJavaArrayOfStrings(env, titles).obj(),
61 ToJavaArrayOfStrings(env, urls).obj());
62 }
63
64 private:
65 friend class base::RefCounted<NativeCallback>;
66 ~NativeCallback() {}
67
68 void ExtractMostVisitedTitlesAndURLs(
69 const history::MostVisitedURLList& visited_list,
70 std::vector<string16>* titles,
71 std::vector<std::string>* urls) {
72 for (size_t i = 0; i < visited_list.size() && i < num_results_; ++i) {
73 const history::MostVisitedURL& visited = visited_list[i];
74
75 if (visited.url.is_empty())
76 break; // This is the signal that there are no more real visited sites.
77
78 titles->push_back(visited.title);
79 urls->push_back(visited.url.spec());
80 }
81 }
82
83 ScopedJavaGlobalRef<jobject> j_callback_obj_;
84 size_t num_results_;
85};
86
87SkBitmap ExtractThumbnail(const base::RefCountedMemory& image_data) {
88 scoped_ptr<SkBitmap> image(gfx::JPEGCodec::Decode(
89 image_data.front(),
90 image_data.size()));
91 return image.get() ? *image : SkBitmap();
92}
93
94void OnObtainedThumbnail(
95 ScopedJavaGlobalRef<jobject>* bitmap,
96 ScopedJavaGlobalRef<jobject>* j_callback_ref) {
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
98 JNIEnv* env = AttachCurrentThread();
99 Java_ThumbnailCallback_onMostVisitedURLsThumbnailAvailable(
100 env, j_callback_ref->obj(), bitmap->obj());
101}
102
103void GetUrlThumbnailTask(
104 std::string url_string,
105 scoped_refptr<TopSites> top_sites,
106 ScopedJavaGlobalRef<jobject>* j_callback_ref) {
107 JNIEnv* env = AttachCurrentThread();
108
109 ScopedJavaGlobalRef<jobject>* j_bitmap_ref =
110 new ScopedJavaGlobalRef<jobject>();
111
112 GURL gurl(url_string);
113
114 scoped_refptr<base::RefCountedMemory> data;
115 if (top_sites->GetPageThumbnail(gurl, &data)) {
116 SkBitmap thumbnail_bitmap = ExtractThumbnail(*data.get());
117 if (!thumbnail_bitmap.empty()) {
118 j_bitmap_ref->Reset(
119 env,
120 gfx::ConvertToJavaBitmap(&thumbnail_bitmap).obj());
121 }
122 }
123
124 // Since j_callback_ref is owned by this callback,
125 // when the callback falls out of scope it will be deleted.
126 // We need to pass ownership to the next callback.
127 ScopedJavaGlobalRef<jobject>* j_callback_ref_pass =
128 new ScopedJavaGlobalRef<jobject>(*j_callback_ref);
129 BrowserThread::PostTask(
130 BrowserThread::UI, FROM_HERE,
131 base::Bind(
132 &OnObtainedThumbnail,
133 base::Owned(j_bitmap_ref),base::Owned(j_callback_ref_pass)));
134}
135
136} // namespace
137
138void GetMostVisitedURLs(
139 JNIEnv* env,
140 jclass clazz,
141 jobject j_profile,
142 jobject j_callback_obj,
143 jint num_results) {
144 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
145
146 DCHECK(profile);
147 if (!profile)
148 return;
149
150 TopSites* top_sites = profile->GetTopSites();
[email protected]a4c2f282013-07-20 05:26:05151 if (!top_sites)
152 return;
[email protected]c764b2822013-07-03 04:16:48153
154 scoped_refptr<NativeCallback> native_callback =
155 new NativeCallback(j_callback_obj, static_cast<int>(num_results));
156 top_sites->GetMostVisitedURLs(
157 base::Bind(&NativeCallback::OnMostVisitedURLsAvailable,
158 native_callback));
159}
160
161// May be called from any thread
162void GetURLThumbnail(
163 JNIEnv* env,
164 jclass clazz,
165 jobject j_profile,
166 jstring url,
167 jobject j_callback_obj) {
168 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
169
170 DCHECK(profile);
171 if (!profile)
172 return;
173
174 ScopedJavaGlobalRef<jobject>* j_callback_ref =
175 new ScopedJavaGlobalRef<jobject>();
176 j_callback_ref->Reset(env, j_callback_obj);
177
178 std::string url_string = ConvertJavaStringToUTF8(env, url);
179 scoped_refptr<TopSites> top_sites(profile->GetTopSites());
180 BrowserThread::PostTask(
181 BrowserThread::DB, FROM_HERE, base::Bind(
182 &GetUrlThumbnailTask,
183 url_string,
184 top_sites, base::Owned(j_callback_ref)));
185}
[email protected]a4c2f282013-07-20 05:26:05186
187void BlacklistUrl(JNIEnv* env, jclass clazz, jobject j_profile, jstring j_url) {
188 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
189
190 DCHECK(profile);
191 if (!profile)
192 return;
193
194 TopSites* top_sites = profile->GetTopSites();
195 if (!top_sites)
196 return;
197
198 std::string url_string = ConvertJavaStringToUTF8(env, j_url);
199 top_sites->AddBlacklistedURL(GURL(url_string));
200}