- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / android / most_visited_sites.cc
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/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
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;
29
30 namespace chrome {
31 namespace android {
32
33 bool RegisterMostVisitedSites(JNIEnv* env) {
34   return RegisterNativesImpl(env);
35 }
36
37 }  // namespace android
38 }  // namespace chrome
39
40 namespace {
41
42 class 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
87 SkBitmap 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
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());
101 }
102
103 void 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, false, &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
138 void 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();
151   if (!top_sites)
152     return;
153
154   // TopSites updates itself after a delay. To ensure up-to-date results, force
155   // an update now.
156   top_sites->SyncWithHistory();
157
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,
162                  native_callback));
163 }
164
165 // May be called from any thread
166 void GetURLThumbnail(
167     JNIEnv* env,
168     jclass clazz,
169     jobject j_profile,
170     jstring url,
171     jobject j_callback_obj) {
172   Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
173
174   DCHECK(profile);
175   if (!profile)
176     return;
177
178   ScopedJavaGlobalRef<jobject>* j_callback_ref =
179       new ScopedJavaGlobalRef<jobject>();
180   j_callback_ref->Reset(env, j_callback_obj);
181
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,
187           url_string,
188           top_sites, base::Owned(j_callback_ref)));
189 }
190
191 void BlacklistUrl(JNIEnv* env, jclass clazz, jobject j_profile, jstring j_url) {
192   Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
193
194   DCHECK(profile);
195   if (!profile)
196     return;
197
198   TopSites* top_sites = profile->GetTopSites();
199   if (!top_sites)
200     return;
201
202   std::string url_string = ConvertJavaStringToUTF8(env, j_url);
203   top_sites->AddBlacklistedURL(GURL(url_string));
204 }