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.
5 #include "chrome/browser/android/most_visited_sites.h"
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"
21 using base::android::AttachCurrentThread;
22 using base::android::ConvertUTF8ToJavaString;
23 using base::android::ConvertJavaStringToUTF8;
24 using base::android::ScopedJavaGlobalRef;
25 using base::android::ToJavaArrayOfStrings;
26 using base::android::CheckException;
27 using content::BrowserThread;
28 using history::TopSites;
33 bool RegisterMostVisitedSites(JNIEnv* env) {
34 return RegisterNativesImpl(env);
37 } // namespace android
42 class NativeCallback : public base::RefCounted<NativeCallback> {
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);
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);
56 JNIEnv* env = AttachCurrentThread();
57 Java_MostVisitedURLsCallback_onMostVisitedURLsAvailable(
59 j_callback_obj_.obj(),
60 ToJavaArrayOfStrings(env, titles).obj(),
61 ToJavaArrayOfStrings(env, urls).obj());
65 friend class base::RefCounted<NativeCallback>;
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];
75 if (visited.url.is_empty())
76 break; // This is the signal that there are no more real visited sites.
78 titles->push_back(visited.title);
79 urls->push_back(visited.url.spec());
83 ScopedJavaGlobalRef<jobject> j_callback_obj_;
87 SkBitmap ExtractThumbnail(const base::RefCountedMemory& image_data) {
88 scoped_ptr<SkBitmap> image(gfx::JPEGCodec::Decode(
91 return image.get() ? *image : SkBitmap();
94 void 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());
103 void GetUrlThumbnailTask(
104 std::string url_string,
105 scoped_refptr<TopSites> top_sites,
106 ScopedJavaGlobalRef<jobject>* j_callback_ref) {
107 JNIEnv* env = AttachCurrentThread();
109 ScopedJavaGlobalRef<jobject>* j_bitmap_ref =
110 new ScopedJavaGlobalRef<jobject>();
112 GURL gurl(url_string);
114 scoped_refptr<base::RefCountedMemory> data;
115 if (top_sites->GetPageThumbnail(gurl, false, &data)) {
116 SkBitmap thumbnail_bitmap = ExtractThumbnail(*data.get());
117 if (!thumbnail_bitmap.empty()) {
120 gfx::ConvertToJavaBitmap(&thumbnail_bitmap).obj());
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,
132 &OnObtainedThumbnail,
133 base::Owned(j_bitmap_ref),base::Owned(j_callback_ref_pass)));
138 void GetMostVisitedURLs(
142 jobject j_callback_obj,
144 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
150 TopSites* top_sites = profile->GetTopSites();
154 // TopSites updates itself after a delay. To ensure up-to-date results, force
156 top_sites->SyncWithHistory();
158 scoped_refptr<NativeCallback> native_callback =
159 new NativeCallback(j_callback_obj, static_cast<int>(num_results));
160 top_sites->GetMostVisitedURLs(
161 base::Bind(&NativeCallback::OnMostVisitedURLsAvailable,
165 // May be called from any thread
166 void GetURLThumbnail(
171 jobject j_callback_obj) {
172 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
178 ScopedJavaGlobalRef<jobject>* j_callback_ref =
179 new ScopedJavaGlobalRef<jobject>();
180 j_callback_ref->Reset(env, j_callback_obj);
182 std::string url_string = ConvertJavaStringToUTF8(env, url);
183 scoped_refptr<TopSites> top_sites(profile->GetTopSites());
184 BrowserThread::PostTask(
185 BrowserThread::DB, FROM_HERE, base::Bind(
186 &GetUrlThumbnailTask,
188 top_sites, base::Owned(j_callback_ref)));
191 void BlacklistUrl(JNIEnv* env, jclass clazz, jobject j_profile, jstring j_url) {
192 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
198 TopSites* top_sites = profile->GetTopSites();
202 std::string url_string = ConvertJavaStringToUTF8(env, j_url);
203 top_sites->AddBlacklistedURL(GURL(url_string));