1 // Copyright 2014 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/enhanced_bookmarks/android/enhanced_bookmarks_bridge.h"
7 #include "base/android/jni_array.h"
8 #include "base/android/jni_string.h"
9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
11 #include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_android.h"
12 #include "chrome/browser/enhanced_bookmarks/android/bookmark_image_service_factory.h"
13 #include "chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.h"
14 #include "chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service_factory.h"
15 #include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h"
16 #include "chrome/browser/profiles/profile_android.h"
17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
18 #include "chrome/browser/signin/signin_manager_factory.h"
19 #include "chrome/common/chrome_version_info.h"
20 #include "chrome/common/pref_names.h"
21 #include "components/bookmarks/browser/bookmark_model.h"
22 #include "components/bookmarks/browser/bookmark_utils.h"
23 #include "components/bookmarks/common/android/bookmark_id.h"
24 #include "components/bookmarks/common/android/bookmark_type.h"
25 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
26 #include "components/enhanced_bookmarks/image_record.h"
27 #include "components/signin/core/browser/signin_manager.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/web_contents.h"
30 #include "jni/EnhancedBookmarksBridge_jni.h"
31 #include "ui/gfx/android/java_bitmap.h"
32 #include "ui/gfx/image/image.h"
34 using base::android::AttachCurrentThread
;
35 using base::android::ScopedJavaGlobalRef
;
36 using bookmarks::android::JavaBookmarkIdCreateBookmarkId
;
37 using bookmarks::android::JavaBookmarkIdGetId
;
38 using bookmarks::android::JavaBookmarkIdGetType
;
39 using bookmarks::BookmarkNode
;
40 using bookmarks::BookmarkType
;
41 using content::WebContents
;
42 using content::BrowserThread
;
43 using enhanced_bookmarks::ImageRecord
;
47 void Callback(ScopedJavaGlobalRef
<jobject
>* j_callback
,
48 scoped_refptr
<ImageRecord
> image_record
) {
49 JNIEnv
* env
= base::android::AttachCurrentThread();
51 scoped_ptr
<ScopedJavaGlobalRef
<jobject
> > j_callback_ptr(j_callback
);
52 ScopedJavaLocalRef
<jstring
> j_url
=
53 base::android::ConvertUTF8ToJavaString(env
, image_record
->url
.spec());
55 SkBitmap bitmap
= image_record
->image
->AsBitmap();
56 ScopedJavaLocalRef
<jobject
> j_bitmap
;
57 if (!bitmap
.isNull()) {
58 j_bitmap
= gfx::ConvertToJavaBitmap(&bitmap
);
61 enhanced_bookmarks::android::Java_SalientImageCallback_onSalientImageReady(
62 env
, j_callback_ptr
->obj(), j_bitmap
.Release(), j_url
.Release());
67 namespace enhanced_bookmarks
{
70 EnhancedBookmarksBridge::EnhancedBookmarksBridge(JNIEnv
* env
,
72 Profile
* profile
) : weak_java_ref_(env
, obj
) {
74 enhanced_bookmark_model_
=
75 EnhancedBookmarkModelFactory::GetForBrowserContext(profile_
);
76 enhanced_bookmark_model_
->SetVersionSuffix(chrome::VersionInfo().OSType());
78 ChromeBookmarkServerClusterServiceFactory::GetForBrowserContext(profile_
);
79 cluster_service_
->AddObserver(this);
80 bookmark_image_service_
= static_cast<BookmarkImageServiceAndroid
*>(
81 BookmarkImageServiceFactory::GetForBrowserContext(profile_
));
82 search_service_
.reset(new BookmarkServerSearchService(
83 profile_
->GetRequestContext(),
84 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
),
85 SigninManagerFactory::GetForProfile(profile_
),
86 EnhancedBookmarkModelFactory::GetForBrowserContext(profile_
)));
87 search_service_
->AddObserver(this);
90 EnhancedBookmarksBridge::~EnhancedBookmarksBridge() {
91 cluster_service_
->RemoveObserver(this);
92 search_service_
->RemoveObserver(this);
95 void EnhancedBookmarksBridge::Destroy(JNIEnv
*, jobject
) {
99 void EnhancedBookmarksBridge::SalientImageForUrl(JNIEnv
* env
,
102 jobject j_callback
) {
105 GURL
url(base::android::ConvertJavaStringToUTF16(env
, j_url
));
106 scoped_ptr
<ScopedJavaGlobalRef
<jobject
>> j_callback_ptr(
107 new ScopedJavaGlobalRef
<jobject
>());
108 j_callback_ptr
->Reset(env
, j_callback
);
109 bookmark_image_service_
->SalientImageForUrl(
110 url
, base::Bind(&Callback
, j_callback_ptr
.release()));
113 void EnhancedBookmarksBridge::FetchImageForTab(JNIEnv
* env
,
115 jobject j_web_contents
) {
116 WebContents
* web_contents
= WebContents::FromJavaWebContents(j_web_contents
);
117 bookmark_image_service_
->RetrieveSalientImageFromContext(
118 web_contents
->GetMainFrame(), web_contents
->GetURL(), true);
121 ScopedJavaLocalRef
<jstring
> EnhancedBookmarksBridge::GetBookmarkDescription(
122 JNIEnv
* env
, jobject obj
, jlong id
, jint type
) {
123 DCHECK(enhanced_bookmark_model_
->loaded());
124 if (type
!= BookmarkType::BOOKMARK_TYPE_NORMAL
) {
125 return base::android::ConvertUTF8ToJavaString(env
, std::string());
128 const BookmarkNode
* node
= bookmarks::GetBookmarkNodeByID(
129 enhanced_bookmark_model_
->bookmark_model(), static_cast<int64
>(id
));
131 return node
? base::android::ConvertUTF8ToJavaString(
132 env
, enhanced_bookmark_model_
->GetDescription(node
))
133 : ScopedJavaLocalRef
<jstring
>();
136 void EnhancedBookmarksBridge::SetBookmarkDescription(JNIEnv
* env
,
140 jstring description
) {
141 DCHECK(enhanced_bookmark_model_
->loaded());
142 DCHECK_EQ(type
, BookmarkType::BOOKMARK_TYPE_NORMAL
);
144 const BookmarkNode
* node
= bookmarks::GetBookmarkNodeByID(
145 enhanced_bookmark_model_
->bookmark_model(), static_cast<int64
>(id
));
147 enhanced_bookmark_model_
->SetDescription(
148 node
, base::android::ConvertJavaStringToUTF8(env
, description
));
151 ScopedJavaLocalRef
<jobjectArray
> EnhancedBookmarksBridge::GetFiltersForBookmark(
156 DCHECK(enhanced_bookmark_model_
->loaded());
157 if (type
!= BookmarkType::BOOKMARK_TYPE_NORMAL
) {
158 return base::android::ToJavaArrayOfStrings(env
, std::vector
<std::string
>());
161 const BookmarkNode
* node
= bookmarks::GetBookmarkNodeByID(
162 enhanced_bookmark_model_
->bookmark_model(), static_cast<int64
>(id
));
163 std::vector
<std::string
> filters
=
164 cluster_service_
->ClustersForBookmark(node
);
165 return base::android::ToJavaArrayOfStrings(env
, filters
);
168 void EnhancedBookmarksBridge::GetBookmarksForFilter(JNIEnv
* env
,
171 jobject j_result_obj
) {
172 DCHECK(enhanced_bookmark_model_
->loaded());
173 const std::string title
=
174 base::android::ConvertJavaStringToUTF8(env
, j_filter
);
175 const std::vector
<const BookmarkNode
*> bookmarks
=
176 cluster_service_
->BookmarksForClusterNamed(title
);
177 for (const BookmarkNode
* node
: bookmarks
) {
178 Java_EnhancedBookmarksBridge_addToBookmarkIdList(
179 env
, j_result_obj
, node
->id(), node
->type());
183 ScopedJavaLocalRef
<jobjectArray
> EnhancedBookmarksBridge::GetFilters(
186 DCHECK(enhanced_bookmark_model_
->loaded());
187 const std::vector
<std::string
> filters
= cluster_service_
->GetClusters();
188 return base::android::ToJavaArrayOfStrings(env
, filters
);
191 ScopedJavaLocalRef
<jobject
> EnhancedBookmarksBridge::AddFolder(JNIEnv
* env
,
193 jobject j_parent_id_obj
,
196 DCHECK(enhanced_bookmark_model_
->loaded());
197 long bookmark_id
= JavaBookmarkIdGetId(env
, j_parent_id_obj
);
198 const BookmarkNode
* parent
= bookmarks::GetBookmarkNodeByID(
199 enhanced_bookmark_model_
->bookmark_model(),
200 static_cast<int64
>(bookmark_id
));
201 const BookmarkNode
* new_node
= enhanced_bookmark_model_
->AddFolder(
202 parent
, index
, base::android::ConvertJavaStringToUTF16(env
, j_title
));
205 return ScopedJavaLocalRef
<jobject
>();
207 ScopedJavaLocalRef
<jobject
> new_java_obj
= JavaBookmarkIdCreateBookmarkId(
208 env
, new_node
->id(), BookmarkType::BOOKMARK_TYPE_NORMAL
);
212 void EnhancedBookmarksBridge::MoveBookmark(JNIEnv
* env
,
214 jobject j_bookmark_id_obj
,
215 jobject j_parent_id_obj
) {
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
217 DCHECK(enhanced_bookmark_model_
->loaded());
219 long bookmark_id
= JavaBookmarkIdGetId(env
, j_bookmark_id_obj
);
220 const BookmarkNode
* node
= bookmarks::GetBookmarkNodeByID(
221 enhanced_bookmark_model_
->bookmark_model(),
222 static_cast<int64
>(bookmark_id
));
223 if (!IsEditable(node
)) {
227 bookmark_id
= JavaBookmarkIdGetId(env
, j_parent_id_obj
);
228 const BookmarkNode
* new_parent_node
= bookmarks::GetBookmarkNodeByID(
229 enhanced_bookmark_model_
->bookmark_model(),
230 static_cast<int64
>(bookmark_id
));
231 enhanced_bookmark_model_
->Move(node
, new_parent_node
,
232 new_parent_node
->child_count());
235 ScopedJavaLocalRef
<jobject
> EnhancedBookmarksBridge::AddBookmark(
238 jobject j_parent_id_obj
,
242 DCHECK(enhanced_bookmark_model_
->loaded());
243 long bookmark_id
= JavaBookmarkIdGetId(env
, j_parent_id_obj
);
244 const BookmarkNode
* parent
= bookmarks::GetBookmarkNodeByID(
245 enhanced_bookmark_model_
->bookmark_model(),
246 static_cast<int64
>(bookmark_id
));
248 const BookmarkNode
* new_node
= enhanced_bookmark_model_
->AddURL(
251 base::android::ConvertJavaStringToUTF16(env
, j_title
),
252 GURL(base::android::ConvertJavaStringToUTF16(env
, j_url
)),
256 return ScopedJavaLocalRef
<jobject
>();
258 ScopedJavaLocalRef
<jobject
> new_java_obj
= JavaBookmarkIdCreateBookmarkId(
259 env
, new_node
->id(), BookmarkType::BOOKMARK_TYPE_NORMAL
);
263 void EnhancedBookmarksBridge::SendSearchRequest(JNIEnv
* env
,
266 search_service_
->Search(base::android::ConvertJavaStringToUTF8(env
, j_query
));
269 ScopedJavaLocalRef
<jobject
> EnhancedBookmarksBridge::GetSearchResults(
273 DCHECK(enhanced_bookmark_model_
->loaded());
275 ScopedJavaLocalRef
<jobject
> j_list
=
276 Java_EnhancedBookmarksBridge_createBookmarkIdList(env
);
277 scoped_ptr
<std::vector
<const BookmarkNode
*>> results
=
278 search_service_
->ResultForQuery(
279 base::android::ConvertJavaStringToUTF8(env
, j_query
));
281 // If result is null, return a null java reference.
283 return ScopedJavaLocalRef
<jobject
>();
285 for (const BookmarkNode
* node
: *results
) {
286 Java_EnhancedBookmarksBridge_addToBookmarkIdList(env
, j_list
.obj(),
287 node
->id(), node
->type());
292 void EnhancedBookmarksBridge::OnChange(BookmarkServerService
* service
) {
293 DCHECK(enhanced_bookmark_model_
->loaded());
294 JNIEnv
* env
= AttachCurrentThread();
296 ScopedJavaLocalRef
<jobject
> obj
= weak_java_ref_
.get(env
);
300 if (service
== cluster_service_
) {
301 Java_EnhancedBookmarksBridge_onFiltersChanged(env
, obj
.obj());
302 } else if (service
== search_service_
.get()) {
303 Java_EnhancedBookmarksBridge_onSearchResultReturned(env
, obj
.obj());
307 bool EnhancedBookmarksBridge::IsEditable(const BookmarkNode
* node
) const {
308 if (!node
|| (node
->type() != BookmarkNode::FOLDER
&&
309 node
->type() != BookmarkNode::URL
)) {
312 return profile_
->GetPrefs()->GetBoolean(
313 bookmarks::prefs::kEditBookmarksEnabled
);
316 static jlong
Init(JNIEnv
* env
, jobject obj
, jobject j_profile
) {
317 return reinterpret_cast<jlong
>(new EnhancedBookmarksBridge(
318 env
, obj
, ProfileAndroid::FromProfileAndroid(j_profile
)));
321 bool RegisterEnhancedBookmarksBridge(JNIEnv
* env
) {
322 return RegisterNativesImpl(env
);
325 } // namespace android
326 } // namespace enhanced_bookmarks