Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / android / most_visited_sites.cc
blob5016cb4e00ea68ca23860a8553f147ac1a5ea2fe
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/chrome_notification_types.h"
12 #include "chrome/browser/history/history_types.h"
13 #include "chrome/browser/history/top_sites.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_android.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/notification_source.h"
18 #include "jni/MostVisitedSites_jni.h"
19 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "ui/gfx/android/java_bitmap.h"
21 #include "ui/gfx/codec/jpeg_codec.h"
23 using base::android::AttachCurrentThread;
24 using base::android::ConvertUTF8ToJavaString;
25 using base::android::ConvertJavaStringToUTF8;
26 using base::android::ScopedJavaGlobalRef;
27 using base::android::ToJavaArrayOfStrings;
28 using base::android::CheckException;
29 using content::BrowserThread;
30 using history::TopSites;
32 namespace {
34 void ExtractMostVisitedTitlesAndURLs(
35 const history::MostVisitedURLList& visited_list,
36 std::vector<base::string16>* titles,
37 std::vector<std::string>* urls,
38 int num_sites) {
39 size_t max = static_cast<size_t>(num_sites);
40 for (size_t i = 0; i < visited_list.size() && i < max; ++i) {
41 const history::MostVisitedURL& visited = visited_list[i];
43 if (visited.url.is_empty())
44 break; // This is the signal that there are no more real visited sites.
46 titles->push_back(visited.title);
47 urls->push_back(visited.url.spec());
51 void OnMostVisitedURLsAvailable(
52 ScopedJavaGlobalRef<jobject>* j_observer,
53 int num_sites,
54 const history::MostVisitedURLList& visited_list) {
55 std::vector<base::string16> titles;
56 std::vector<std::string> urls;
57 ExtractMostVisitedTitlesAndURLs(visited_list, &titles, &urls, num_sites);
59 JNIEnv* env = AttachCurrentThread();
60 Java_MostVisitedURLsObserver_onMostVisitedURLsAvailable(
61 env,
62 j_observer->obj(),
63 ToJavaArrayOfStrings(env, titles).obj(),
64 ToJavaArrayOfStrings(env, urls).obj());
67 SkBitmap ExtractThumbnail(const base::RefCountedMemory& image_data) {
68 scoped_ptr<SkBitmap> image(gfx::JPEGCodec::Decode(
69 image_data.front(),
70 image_data.size()));
71 return image.get() ? *image : SkBitmap();
74 void OnObtainedThumbnail(
75 ScopedJavaGlobalRef<jobject>* bitmap,
76 ScopedJavaGlobalRef<jobject>* j_callback) {
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
78 JNIEnv* env = AttachCurrentThread();
79 Java_ThumbnailCallback_onMostVisitedURLsThumbnailAvailable(
80 env, j_callback->obj(), bitmap->obj());
83 void GetUrlThumbnailTask(
84 std::string url_string,
85 scoped_refptr<TopSites> top_sites,
86 ScopedJavaGlobalRef<jobject>* j_callback) {
87 JNIEnv* env = AttachCurrentThread();
89 ScopedJavaGlobalRef<jobject>* j_bitmap_ref =
90 new ScopedJavaGlobalRef<jobject>();
92 GURL gurl(url_string);
94 scoped_refptr<base::RefCountedMemory> data;
95 if (top_sites->GetPageThumbnail(gurl, false, &data)) {
96 SkBitmap thumbnail_bitmap = ExtractThumbnail(*data.get());
97 if (!thumbnail_bitmap.empty()) {
98 j_bitmap_ref->Reset(
99 env,
100 gfx::ConvertToJavaBitmap(&thumbnail_bitmap).obj());
104 // Since j_callback is owned by this callback, when the callback falls out of
105 // scope it will be deleted. We need to pass ownership to the next callback.
106 ScopedJavaGlobalRef<jobject>* j_callback_pass =
107 new ScopedJavaGlobalRef<jobject>(*j_callback);
108 BrowserThread::PostTask(
109 BrowserThread::UI, FROM_HERE,
110 base::Bind(
111 &OnObtainedThumbnail,
112 base::Owned(j_bitmap_ref), base::Owned(j_callback_pass)));
115 } // namespace
117 MostVisitedSites::MostVisitedSites(Profile* profile)
118 : profile_(profile), num_sites_(0) {
121 MostVisitedSites::~MostVisitedSites() {
124 void MostVisitedSites::Destroy(JNIEnv* env, jobject obj) {
125 delete this;
128 void MostVisitedSites::SetMostVisitedURLsObserver(JNIEnv* env,
129 jobject obj,
130 jobject j_observer,
131 jint num_sites) {
132 observer_.Reset(env, j_observer);
133 num_sites_ = num_sites;
135 QueryMostVisitedURLs();
137 history::TopSites* top_sites = profile_->GetTopSites();
138 if (top_sites) {
139 // TopSites updates itself after a delay. To ensure up-to-date results,
140 // force an update now.
141 top_sites->SyncWithHistory();
143 // Register for notification when TopSites changes so that we can update
144 // ourself.
145 registrar_.Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED,
146 content::Source<history::TopSites>(top_sites));
150 // May be called from any thread
151 void MostVisitedSites::GetURLThumbnail(JNIEnv* env,
152 jobject obj,
153 jstring url,
154 jobject j_callback_obj) {
155 ScopedJavaGlobalRef<jobject>* j_callback =
156 new ScopedJavaGlobalRef<jobject>();
157 j_callback->Reset(env, j_callback_obj);
159 std::string url_string = ConvertJavaStringToUTF8(env, url);
160 scoped_refptr<TopSites> top_sites(profile_->GetTopSites());
161 BrowserThread::PostTask(
162 BrowserThread::DB, FROM_HERE, base::Bind(
163 &GetUrlThumbnailTask,
164 url_string,
165 top_sites, base::Owned(j_callback)));
168 void MostVisitedSites::BlacklistUrl(JNIEnv* env,
169 jobject obj,
170 jstring j_url) {
171 TopSites* top_sites = profile_->GetTopSites();
172 if (!top_sites)
173 return;
175 std::string url_string = ConvertJavaStringToUTF8(env, j_url);
176 top_sites->AddBlacklistedURL(GURL(url_string));
179 void MostVisitedSites::Observe(int type,
180 const content::NotificationSource& source,
181 const content::NotificationDetails& details) {
182 DCHECK_EQ(type, chrome::NOTIFICATION_TOP_SITES_CHANGED);
184 // Most visited urls changed, query again.
185 QueryMostVisitedURLs();
188 // static
189 bool MostVisitedSites::Register(JNIEnv* env) {
190 return RegisterNativesImpl(env);
193 void MostVisitedSites::QueryMostVisitedURLs() {
194 TopSites* top_sites = profile_->GetTopSites();
195 if (!top_sites)
196 return;
198 top_sites->GetMostVisitedURLs(
199 base::Bind(
200 &OnMostVisitedURLsAvailable,
201 base::Owned(new ScopedJavaGlobalRef<jobject>(observer_)),
202 num_sites_),
203 false);
206 static jlong Init(JNIEnv* env, jobject obj, jobject jprofile) {
207 MostVisitedSites* most_visited_sites =
208 new MostVisitedSites(ProfileAndroid::FromProfileAndroid(jprofile));
209 return reinterpret_cast<intptr_t>(most_visited_sites);