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_factory.h"
12 #include "chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service.h"
13 #include "chrome/browser/enhanced_bookmarks/chrome_bookmark_server_cluster_service_factory.h"
14 #include "chrome/browser/enhanced_bookmarks/enhanced_bookmark_model_factory.h"
15 #include "chrome/browser/profiles/profile_android.h"
16 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
17 #include "chrome/browser/signin/signin_manager_factory.h"
18 #include "chrome/common/chrome_version_info.h"
19 #include "chrome/common/pref_names.h"
20 #include "components/bookmarks/browser/bookmark_model.h"
21 #include "components/bookmarks/browser/bookmark_utils.h"
22 #include "components/bookmarks/common/android/bookmark_id.h"
23 #include "components/bookmarks/common/android/bookmark_type.h"
24 #include "components/enhanced_bookmarks/bookmark_image_service.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 "jni/EnhancedBookmarksBridge_jni.h"
30 #include "ui/gfx/android/java_bitmap.h"
31 #include "ui/gfx/image/image.h"
33 using base::android::AttachCurrentThread
;
34 using base::android::ScopedJavaGlobalRef
;
35 using bookmarks::android::JavaBookmarkIdCreateBookmarkId
;
36 using bookmarks::android::JavaBookmarkIdGetId
;
37 using bookmarks::android::JavaBookmarkIdGetType
;
38 using bookmarks::BookmarkNode
;
39 using bookmarks::BookmarkType
;
40 using content::BrowserThread
;
41 using enhanced_bookmarks::ImageRecord
;
45 void Callback(ScopedJavaGlobalRef
<jobject
>* j_callback
,
46 const ImageRecord
& image_record
) {
47 JNIEnv
* env
= base::android::AttachCurrentThread();
49 scoped_ptr
<ScopedJavaGlobalRef
<jobject
> > j_callback_ptr(j_callback
);
50 ScopedJavaLocalRef
<jstring
> j_url
=
51 base::android::ConvertUTF8ToJavaString(env
, image_record
.url
.spec());
53 SkBitmap bitmap
= image_record
.image
.AsBitmap();
54 ScopedJavaLocalRef
<jobject
> j_bitmap
;
55 if (!bitmap
.isNull()) {
56 j_bitmap
= gfx::ConvertToJavaBitmap(&bitmap
);
59 enhanced_bookmarks::android::Java_SalientImageCallback_onSalientImageReady(
60 env
, j_callback_ptr
->obj(), j_bitmap
.Release(), j_url
.Release());
65 namespace enhanced_bookmarks
{
68 EnhancedBookmarksBridge::EnhancedBookmarksBridge(JNIEnv
* env
,
70 Profile
* profile
) : weak_java_ref_(env
, obj
) {
72 enhanced_bookmark_model_
=
73 EnhancedBookmarkModelFactory::GetForBrowserContext(profile_
);
74 enhanced_bookmark_model_
->SetVersionSuffix(chrome::VersionInfo().OSType());
76 ChromeBookmarkServerClusterServiceFactory::GetForBrowserContext(profile_
);
77 cluster_service_
->AddObserver(this);
78 bookmark_image_service_
=
79 BookmarkImageServiceFactory::GetForBrowserContext(profile_
);
80 search_service_
.reset(new BookmarkServerSearchService(
81 profile_
->GetRequestContext(),
82 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
),
83 SigninManagerFactory::GetForProfile(profile_
),
84 EnhancedBookmarkModelFactory::GetForBrowserContext(profile_
)));
85 search_service_
->AddObserver(this);
88 EnhancedBookmarksBridge::~EnhancedBookmarksBridge() {
89 cluster_service_
->RemoveObserver(this);
90 search_service_
->RemoveObserver(this);
93 void EnhancedBookmarksBridge::Destroy(JNIEnv
*, jobject
) {
97 void EnhancedBookmarksBridge::SalientImageForUrl(JNIEnv
* env
,
100 jobject j_callback
) {
103 GURL
url(base::android::ConvertJavaStringToUTF16(env
, j_url
));
104 scoped_ptr
<ScopedJavaGlobalRef
<jobject
>> j_callback_ptr(
105 new ScopedJavaGlobalRef
<jobject
>());
106 j_callback_ptr
->Reset(env
, j_callback
);
107 bookmark_image_service_
->SalientImageForUrl(
108 url
, base::Bind(&Callback
, j_callback_ptr
.release()));
111 ScopedJavaLocalRef
<jstring
> EnhancedBookmarksBridge::GetBookmarkDescription(
112 JNIEnv
* env
, jobject obj
, jlong id
, jint type
) {
113 DCHECK(enhanced_bookmark_model_
->loaded());
114 if (type
!= BookmarkType::BOOKMARK_TYPE_NORMAL
) {
115 return base::android::ConvertUTF8ToJavaString(env
, std::string());
118 const BookmarkNode
* node
= bookmarks::GetBookmarkNodeByID(
119 enhanced_bookmark_model_
->bookmark_model(), static_cast<int64
>(id
));
121 return node
? base::android::ConvertUTF8ToJavaString(
122 env
, enhanced_bookmark_model_
->GetDescription(node
))
123 : ScopedJavaLocalRef
<jstring
>();
126 void EnhancedBookmarksBridge::SetBookmarkDescription(JNIEnv
* env
,
130 jstring description
) {
131 DCHECK(enhanced_bookmark_model_
->loaded());
132 DCHECK_EQ(type
, BookmarkType::BOOKMARK_TYPE_NORMAL
);
134 const BookmarkNode
* node
= bookmarks::GetBookmarkNodeByID(
135 enhanced_bookmark_model_
->bookmark_model(), static_cast<int64
>(id
));
137 enhanced_bookmark_model_
->SetDescription(
138 node
, base::android::ConvertJavaStringToUTF8(env
, description
));
141 ScopedJavaLocalRef
<jobjectArray
> EnhancedBookmarksBridge::GetFiltersForBookmark(
146 DCHECK(enhanced_bookmark_model_
->loaded());
147 if (type
!= BookmarkType::BOOKMARK_TYPE_NORMAL
) {
148 return base::android::ToJavaArrayOfStrings(env
, std::vector
<std::string
>());
151 const BookmarkNode
* node
= bookmarks::GetBookmarkNodeByID(
152 enhanced_bookmark_model_
->bookmark_model(), static_cast<int64
>(id
));
153 std::vector
<std::string
> filters
=
154 cluster_service_
->ClustersForBookmark(node
);
155 return base::android::ToJavaArrayOfStrings(env
, filters
);
158 void EnhancedBookmarksBridge::GetBookmarksForFilter(JNIEnv
* env
,
161 jobject j_result_obj
) {
162 DCHECK(enhanced_bookmark_model_
->loaded());
163 const std::string title
=
164 base::android::ConvertJavaStringToUTF8(env
, j_filter
);
165 const std::vector
<const BookmarkNode
*> bookmarks
=
166 cluster_service_
->BookmarksForClusterNamed(title
);
167 for (const BookmarkNode
* node
: bookmarks
) {
168 Java_EnhancedBookmarksBridge_addToBookmarkIdList(
169 env
, j_result_obj
, node
->id(), node
->type());
173 ScopedJavaLocalRef
<jobjectArray
> EnhancedBookmarksBridge::GetFilters(
176 DCHECK(enhanced_bookmark_model_
->loaded());
177 const std::vector
<std::string
> filters
= cluster_service_
->GetClusters();
178 return base::android::ToJavaArrayOfStrings(env
, filters
);
181 ScopedJavaLocalRef
<jobject
> EnhancedBookmarksBridge::AddFolder(JNIEnv
* env
,
183 jobject j_parent_id_obj
,
186 DCHECK(enhanced_bookmark_model_
->loaded());
187 long bookmark_id
= JavaBookmarkIdGetId(env
, j_parent_id_obj
);
188 const BookmarkNode
* parent
= bookmarks::GetBookmarkNodeByID(
189 enhanced_bookmark_model_
->bookmark_model(),
190 static_cast<int64
>(bookmark_id
));
191 const BookmarkNode
* new_node
= enhanced_bookmark_model_
->AddFolder(
192 parent
, index
, base::android::ConvertJavaStringToUTF16(env
, j_title
));
195 return ScopedJavaLocalRef
<jobject
>();
197 ScopedJavaLocalRef
<jobject
> new_java_obj
=
198 JavaBookmarkIdCreateBookmarkId(env
, new_node
->id(), new_node
->type());
202 void EnhancedBookmarksBridge::MoveBookmark(JNIEnv
* env
,
204 jobject j_bookmark_id_obj
,
205 jobject j_parent_id_obj
) {
206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
207 DCHECK(enhanced_bookmark_model_
->loaded());
209 long bookmark_id
= JavaBookmarkIdGetId(env
, j_bookmark_id_obj
);
210 const BookmarkNode
* node
= bookmarks::GetBookmarkNodeByID(
211 enhanced_bookmark_model_
->bookmark_model(),
212 static_cast<int64
>(bookmark_id
));
213 if (!IsEditable(node
)) {
217 bookmark_id
= JavaBookmarkIdGetId(env
, j_parent_id_obj
);
218 const BookmarkNode
* new_parent_node
= bookmarks::GetBookmarkNodeByID(
219 enhanced_bookmark_model_
->bookmark_model(),
220 static_cast<int64
>(bookmark_id
));
221 enhanced_bookmark_model_
->Move(node
, new_parent_node
,
222 new_parent_node
->child_count());
225 ScopedJavaLocalRef
<jobject
> EnhancedBookmarksBridge::AddBookmark(
228 jobject j_parent_id_obj
,
232 DCHECK(enhanced_bookmark_model_
->loaded());
233 long bookmark_id
= JavaBookmarkIdGetId(env
, j_parent_id_obj
);
234 const BookmarkNode
* parent
= bookmarks::GetBookmarkNodeByID(
235 enhanced_bookmark_model_
->bookmark_model(),
236 static_cast<int64
>(bookmark_id
));
238 const BookmarkNode
* new_node
= enhanced_bookmark_model_
->AddURL(
241 base::android::ConvertJavaStringToUTF16(env
, j_title
),
242 GURL(base::android::ConvertJavaStringToUTF16(env
, j_url
)),
246 return ScopedJavaLocalRef
<jobject
>();
248 ScopedJavaLocalRef
<jobject
> new_java_obj
=
249 JavaBookmarkIdCreateBookmarkId(env
, new_node
->id(), new_node
->type());
253 void EnhancedBookmarksBridge::SendSearchRequest(JNIEnv
* env
,
256 search_service_
->Search(base::android::ConvertJavaStringToUTF8(env
, j_query
));
259 ScopedJavaLocalRef
<jobject
> EnhancedBookmarksBridge::GetSearchResults(
263 DCHECK(enhanced_bookmark_model_
->loaded());
265 ScopedJavaLocalRef
<jobject
> j_list
=
266 Java_EnhancedBookmarksBridge_createBookmarkIdList(env
);
267 scoped_ptr
<std::vector
<const BookmarkNode
*>> results
=
268 search_service_
->ResultForQuery(
269 base::android::ConvertJavaStringToUTF8(env
, j_query
));
271 // If result is null, return a null java reference.
273 return ScopedJavaLocalRef
<jobject
>();
275 for (const BookmarkNode
* node
: *results
) {
276 Java_EnhancedBookmarksBridge_addToBookmarkIdList(env
, j_list
.obj(),
277 node
->id(), node
->type());
282 void EnhancedBookmarksBridge::OnChange(BookmarkServerService
* service
) {
283 DCHECK(enhanced_bookmark_model_
->loaded());
284 JNIEnv
* env
= AttachCurrentThread();
286 ScopedJavaLocalRef
<jobject
> obj
= weak_java_ref_
.get(env
);
290 if (service
== cluster_service_
) {
291 Java_EnhancedBookmarksBridge_onFiltersChanged(env
, obj
.obj());
292 } else if (service
== search_service_
.get()) {
293 Java_EnhancedBookmarksBridge_onSearchResultReturned(env
, obj
.obj());
297 bool EnhancedBookmarksBridge::IsEditable(const BookmarkNode
* node
) const {
298 if (!node
|| (node
->type() != BookmarkNode::FOLDER
&&
299 node
->type() != BookmarkNode::URL
)) {
302 return profile_
->GetPrefs()->GetBoolean(
303 bookmarks::prefs::kEditBookmarksEnabled
);
306 static jlong
Init(JNIEnv
* env
, jobject obj
, jobject j_profile
) {
307 return reinterpret_cast<jlong
>(new EnhancedBookmarksBridge(
308 env
, obj
, ProfileAndroid::FromProfileAndroid(j_profile
)));
311 bool RegisterEnhancedBookmarksBridge(JNIEnv
* env
) {
312 return RegisterNativesImpl(env
);
315 } // namespace android
316 } // namespace enhanced_bookmarks