OLD | NEW |
| (Empty) |
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/bookmarks/bookmarks_bridge.h" | |
6 | |
7 #include <stddef.h> | |
8 #include <stdint.h> | |
9 | |
10 #include "base/android/jni_array.h" | |
11 #include "base/android/jni_string.h" | |
12 #include "base/containers/stack_container.h" | |
13 #include "base/i18n/string_compare.h" | |
14 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | |
15 #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" | |
16 #include "chrome/browser/profiles/incognito_helpers.h" | |
17 #include "chrome/browser/profiles/profile.h" | |
18 #include "chrome/browser/profiles/profile_android.h" | |
19 #include "chrome/browser/signin/signin_manager_factory.h" | |
20 #include "chrome/browser/undo/bookmark_undo_service_factory.h" | |
21 #include "components/bookmarks/browser/bookmark_match.h" | |
22 #include "components/bookmarks/browser/bookmark_model.h" | |
23 #include "components/bookmarks/browser/bookmark_utils.h" | |
24 #include "components/bookmarks/browser/scoped_group_bookmark_actions.h" | |
25 #include "components/bookmarks/common/android/bookmark_type.h" | |
26 #include "components/bookmarks/common/bookmark_pref_names.h" | |
27 #include "components/bookmarks/managed/managed_bookmark_service.h" | |
28 #include "components/prefs/pref_service.h" | |
29 #include "components/query_parser/query_parser.h" | |
30 #include "components/signin/core/browser/signin_manager.h" | |
31 #include "components/undo/bookmark_undo_service.h" | |
32 #include "components/undo/undo_manager.h" | |
33 #include "content/public/browser/browser_thread.h" | |
34 #include "grit/components_strings.h" | |
35 #include "jni/BookmarksBridge_jni.h" | |
36 #include "ui/base/l10n/l10n_util.h" | |
37 | |
38 using base::android::AttachCurrentThread; | |
39 using base::android::ConvertUTF8ToJavaString; | |
40 using base::android::ConvertUTF16ToJavaString; | |
41 using base::android::ScopedJavaLocalRef; | |
42 using base::android::ScopedJavaGlobalRef; | |
43 using base::android::ToJavaIntArray; | |
44 using bookmarks::android::JavaBookmarkIdCreateBookmarkId; | |
45 using bookmarks::android::JavaBookmarkIdGetId; | |
46 using bookmarks::android::JavaBookmarkIdGetType; | |
47 using bookmarks::BookmarkModel; | |
48 using bookmarks::BookmarkNode; | |
49 using bookmarks::BookmarkPermanentNode; | |
50 using bookmarks::BookmarkType; | |
51 using content::BrowserThread; | |
52 | |
53 namespace { | |
54 | |
55 class BookmarkNodeCreationTimeCompareFunctor { | |
56 public: | |
57 bool operator()(const BookmarkNode* lhs, const BookmarkNode* rhs) { | |
58 return lhs->date_added().ToJavaTime() > rhs->date_added().ToJavaTime(); | |
59 } | |
60 }; | |
61 | |
62 class BookmarkTitleComparer { | |
63 public: | |
64 explicit BookmarkTitleComparer(BookmarksBridge* bookmarks_bridge, | |
65 const icu::Collator* collator) | |
66 : bookmarks_bridge_(bookmarks_bridge), | |
67 collator_(collator) {} | |
68 | |
69 bool operator()(const BookmarkNode* lhs, const BookmarkNode* rhs) { | |
70 if (collator_) { | |
71 return base::i18n::CompareString16WithCollator( | |
72 *collator_, bookmarks_bridge_->GetTitle(lhs), | |
73 bookmarks_bridge_->GetTitle(rhs)) == UCOL_LESS; | |
74 } else { | |
75 return lhs->GetTitle() < rhs->GetTitle(); | |
76 } | |
77 } | |
78 | |
79 private: | |
80 BookmarksBridge* bookmarks_bridge_; // weak | |
81 const icu::Collator* collator_; | |
82 }; | |
83 | |
84 scoped_ptr<icu::Collator> GetICUCollator() { | |
85 UErrorCode error = U_ZERO_ERROR; | |
86 scoped_ptr<icu::Collator> collator_; | |
87 collator_.reset(icu::Collator::createInstance(error)); | |
88 if (U_FAILURE(error)) | |
89 collator_.reset(NULL); | |
90 | |
91 return collator_; | |
92 } | |
93 | |
94 } // namespace | |
95 | |
96 BookmarksBridge::BookmarksBridge(JNIEnv* env, jobject obj, jobject j_profile) | |
97 : weak_java_ref_(env, obj), | |
98 bookmark_model_(NULL), | |
99 managed_bookmark_service_(NULL), | |
100 partner_bookmarks_shim_(NULL) { | |
101 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
102 profile_ = ProfileAndroid::FromProfileAndroid(j_profile); | |
103 bookmark_model_ = BookmarkModelFactory::GetForProfile(profile_); | |
104 managed_bookmark_service_ = | |
105 ManagedBookmarkServiceFactory::GetForProfile(profile_); | |
106 | |
107 // Registers the notifications we are interested. | |
108 bookmark_model_->AddObserver(this); | |
109 | |
110 // Create the partner Bookmarks shim as early as possible (but don't attach). | |
111 partner_bookmarks_shim_ = PartnerBookmarksShim::BuildForBrowserContext( | |
112 chrome::GetBrowserContextRedirectedInIncognito(profile_)); | |
113 partner_bookmarks_shim_->AddObserver(this); | |
114 | |
115 pref_change_registrar_.Init(profile_->GetPrefs()); | |
116 pref_change_registrar_.Add( | |
117 bookmarks::prefs::kEditBookmarksEnabled, | |
118 base::Bind(&BookmarksBridge::EditBookmarksEnabledChanged, | |
119 base::Unretained(this))); | |
120 | |
121 NotifyIfDoneLoading(); | |
122 | |
123 // Since a sync or import could have started before this class is | |
124 // initialized, we need to make sure that our initial state is | |
125 // up to date. | |
126 if (bookmark_model_->IsDoingExtensiveChanges()) | |
127 ExtensiveBookmarkChangesBeginning(bookmark_model_); | |
128 } | |
129 | |
130 BookmarksBridge::~BookmarksBridge() { | |
131 bookmark_model_->RemoveObserver(this); | |
132 if (partner_bookmarks_shim_) | |
133 partner_bookmarks_shim_->RemoveObserver(this); | |
134 } | |
135 | |
136 void BookmarksBridge::Destroy(JNIEnv*, const JavaParamRef<jobject>&) { | |
137 delete this; | |
138 } | |
139 | |
140 // static | |
141 bool BookmarksBridge::RegisterBookmarksBridge(JNIEnv* env) { | |
142 return RegisterNativesImpl(env); | |
143 } | |
144 | |
145 static jlong Init(JNIEnv* env, | |
146 const JavaParamRef<jobject>& obj, | |
147 const JavaParamRef<jobject>& j_profile) { | |
148 BookmarksBridge* delegate = new BookmarksBridge(env, obj, j_profile); | |
149 return reinterpret_cast<intptr_t>(delegate); | |
150 } | |
151 | |
152 jboolean BookmarksBridge::IsEditBookmarksEnabled( | |
153 JNIEnv* env, | |
154 const JavaParamRef<jobject>& obj) { | |
155 return IsEditBookmarksEnabled(); | |
156 } | |
157 | |
158 void BookmarksBridge::LoadEmptyPartnerBookmarkShimForTesting( | |
159 JNIEnv* env, | |
160 const JavaParamRef<jobject>& obj) { | |
161 if (partner_bookmarks_shim_->IsLoaded()) | |
162 return; | |
163 partner_bookmarks_shim_->SetPartnerBookmarksRoot( | |
164 new BookmarkPermanentNode(0)); | |
165 DCHECK(partner_bookmarks_shim_->IsLoaded()); | |
166 } | |
167 | |
168 ScopedJavaLocalRef<jobject> BookmarksBridge::GetBookmarkByID( | |
169 JNIEnv* env, | |
170 const JavaParamRef<jobject>& obj, | |
171 jlong id, | |
172 jint type) { | |
173 DCHECK(IsLoaded()); | |
174 const BookmarkNode* node = GetNodeByID(id, type); | |
175 return node ? CreateJavaBookmark(node) : ScopedJavaLocalRef<jobject>(); | |
176 } | |
177 | |
178 bool BookmarksBridge::IsDoingExtensiveChanges( | |
179 JNIEnv* env, | |
180 const JavaParamRef<jobject>& obj) { | |
181 return bookmark_model_->IsDoingExtensiveChanges(); | |
182 } | |
183 | |
184 void BookmarksBridge::GetPermanentNodeIDs( | |
185 JNIEnv* env, | |
186 const JavaParamRef<jobject>& obj, | |
187 const JavaParamRef<jobject>& j_result_obj) { | |
188 // TODO(kkimlabs): Remove this function. | |
189 DCHECK(IsLoaded()); | |
190 | |
191 base::StackVector<const BookmarkNode*, 8> permanent_nodes; | |
192 | |
193 // Save all the permanent nodes. | |
194 const BookmarkNode* root_node = bookmark_model_->root_node(); | |
195 permanent_nodes->push_back(root_node); | |
196 for (int i = 0; i < root_node->child_count(); ++i) { | |
197 permanent_nodes->push_back(root_node->GetChild(i)); | |
198 } | |
199 permanent_nodes->push_back( | |
200 partner_bookmarks_shim_->GetPartnerBookmarksRoot()); | |
201 | |
202 // Write the permanent nodes to |j_result_obj|. | |
203 for (base::StackVector<const BookmarkNode*, 8>::ContainerType::const_iterator | |
204 it = permanent_nodes->begin(); | |
205 it != permanent_nodes->end(); | |
206 ++it) { | |
207 if (*it != NULL) { | |
208 Java_BookmarksBridge_addToBookmarkIdList( | |
209 env, j_result_obj, (*it)->id(), GetBookmarkType(*it)); | |
210 } | |
211 } | |
212 } | |
213 | |
214 void BookmarksBridge::GetTopLevelFolderParentIDs( | |
215 JNIEnv* env, | |
216 const JavaParamRef<jobject>& obj, | |
217 const JavaParamRef<jobject>& j_result_obj) { | |
218 Java_BookmarksBridge_addToBookmarkIdList( | |
219 env, j_result_obj, bookmark_model_->root_node()->id(), | |
220 GetBookmarkType(bookmark_model_->root_node())); | |
221 } | |
222 | |
223 void BookmarksBridge::GetTopLevelFolderIDs( | |
224 JNIEnv* env, | |
225 const JavaParamRef<jobject>& obj, | |
226 jboolean get_special, | |
227 jboolean get_normal, | |
228 const JavaParamRef<jobject>& j_result_obj) { | |
229 DCHECK(IsLoaded()); | |
230 std::vector<const BookmarkNode*> top_level_folders; | |
231 | |
232 if (get_special) { | |
233 if (managed_bookmark_service_->managed_node() && | |
234 managed_bookmark_service_->managed_node()->child_count() > 0) { | |
235 top_level_folders.push_back(managed_bookmark_service_->managed_node()); | |
236 } | |
237 if (managed_bookmark_service_->supervised_node() && | |
238 managed_bookmark_service_->supervised_node()->child_count() > 0) { | |
239 top_level_folders.push_back(managed_bookmark_service_->supervised_node()); | |
240 } | |
241 if (partner_bookmarks_shim_->HasPartnerBookmarks() | |
242 && IsReachable(partner_bookmarks_shim_->GetPartnerBookmarksRoot())) { | |
243 top_level_folders.push_back( | |
244 partner_bookmarks_shim_->GetPartnerBookmarksRoot()); | |
245 } | |
246 } | |
247 std::size_t special_count = top_level_folders.size(); | |
248 | |
249 if (get_normal) { | |
250 DCHECK_EQ(bookmark_model_->root_node()->child_count(), 5); | |
251 | |
252 const BookmarkNode* mobile_node = bookmark_model_->mobile_node(); | |
253 for (int i = 0; i < mobile_node->child_count(); ++i) { | |
254 const BookmarkNode* node = mobile_node->GetChild(i); | |
255 if (node->is_folder()) { | |
256 top_level_folders.push_back(node); | |
257 } | |
258 } | |
259 | |
260 const BookmarkNode* bookmark_bar_node = | |
261 bookmark_model_->bookmark_bar_node(); | |
262 for (int i = 0; i < bookmark_bar_node->child_count(); ++i) { | |
263 const BookmarkNode* node = bookmark_bar_node->GetChild(i); | |
264 if (node->is_folder()) { | |
265 top_level_folders.push_back(node); | |
266 } | |
267 } | |
268 | |
269 const BookmarkNode* other_node = bookmark_model_->other_node(); | |
270 for (int i = 0; i < other_node->child_count(); ++i) { | |
271 const BookmarkNode* node = other_node->GetChild(i); | |
272 if (node->is_folder()) { | |
273 top_level_folders.push_back(node); | |
274 } | |
275 } | |
276 | |
277 scoped_ptr<icu::Collator> collator = GetICUCollator(); | |
278 std::stable_sort(top_level_folders.begin() + special_count, | |
279 top_level_folders.end(), | |
280 BookmarkTitleComparer(this, collator.get())); | |
281 } | |
282 | |
283 for (std::vector<const BookmarkNode*>::const_iterator it = | |
284 top_level_folders.begin(); it != top_level_folders.end(); ++it) { | |
285 Java_BookmarksBridge_addToBookmarkIdList(env, | |
286 j_result_obj, | |
287 (*it)->id(), | |
288 GetBookmarkType(*it)); | |
289 } | |
290 } | |
291 | |
292 void BookmarksBridge::GetAllFoldersWithDepths( | |
293 JNIEnv* env, | |
294 const JavaParamRef<jobject>& obj, | |
295 const JavaParamRef<jobject>& j_folders_obj, | |
296 const JavaParamRef<jobject>& j_depths_obj) { | |
297 DCHECK(IsLoaded()); | |
298 | |
299 scoped_ptr<icu::Collator> collator = GetICUCollator(); | |
300 | |
301 // Vector to temporarily contain all child bookmarks at same level for sorting | |
302 std::vector<const BookmarkNode*> bookmarkList; | |
303 | |
304 // Stack for Depth-First Search of bookmark model. It stores nodes and their | |
305 // heights. | |
306 std::stack<std::pair<const BookmarkNode*, int> > stk; | |
307 | |
308 bookmarkList.push_back(bookmark_model_->mobile_node()); | |
309 bookmarkList.push_back(bookmark_model_->bookmark_bar_node()); | |
310 bookmarkList.push_back(bookmark_model_->other_node()); | |
311 | |
312 // Push all sorted top folders in stack and give them depth of 0. | |
313 // Note the order to push folders to stack should be opposite to the order in | |
314 // output. | |
315 for (std::vector<const BookmarkNode*>::reverse_iterator it = | |
316 bookmarkList.rbegin(); | |
317 it != bookmarkList.rend(); | |
318 ++it) { | |
319 stk.push(std::make_pair(*it, 0)); | |
320 } | |
321 | |
322 while (!stk.empty()) { | |
323 const BookmarkNode* node = stk.top().first; | |
324 int depth = stk.top().second; | |
325 stk.pop(); | |
326 Java_BookmarksBridge_addToBookmarkIdListWithDepth(env, | |
327 j_folders_obj, | |
328 node->id(), | |
329 GetBookmarkType(node), | |
330 j_depths_obj, | |
331 depth); | |
332 bookmarkList.clear(); | |
333 for (int i = 0; i < node->child_count(); ++i) { | |
334 const BookmarkNode* child = node->GetChild(i); | |
335 if (child->is_folder() && | |
336 managed_bookmark_service_->CanBeEditedByUser(child)) { | |
337 bookmarkList.push_back(node->GetChild(i)); | |
338 } | |
339 } | |
340 std::stable_sort(bookmarkList.begin(), | |
341 bookmarkList.end(), | |
342 BookmarkTitleComparer(this, collator.get())); | |
343 for (std::vector<const BookmarkNode*>::reverse_iterator it = | |
344 bookmarkList.rbegin(); | |
345 it != bookmarkList.rend(); | |
346 ++it) { | |
347 stk.push(std::make_pair(*it, depth + 1)); | |
348 } | |
349 } | |
350 } | |
351 | |
352 ScopedJavaLocalRef<jobject> BookmarksBridge::GetRootFolderId( | |
353 JNIEnv* env, | |
354 const JavaParamRef<jobject>& obj) { | |
355 const BookmarkNode* root_node = bookmark_model_->root_node(); | |
356 ScopedJavaLocalRef<jobject> folder_id_obj = | |
357 JavaBookmarkIdCreateBookmarkId( | |
358 env, root_node->id(), GetBookmarkType(root_node)); | |
359 return folder_id_obj; | |
360 } | |
361 | |
362 ScopedJavaLocalRef<jobject> BookmarksBridge::GetMobileFolderId( | |
363 JNIEnv* env, | |
364 const JavaParamRef<jobject>& obj) { | |
365 const BookmarkNode* mobile_node = bookmark_model_->mobile_node(); | |
366 ScopedJavaLocalRef<jobject> folder_id_obj = | |
367 JavaBookmarkIdCreateBookmarkId( | |
368 env, mobile_node->id(), GetBookmarkType(mobile_node)); | |
369 return folder_id_obj; | |
370 } | |
371 | |
372 ScopedJavaLocalRef<jobject> BookmarksBridge::GetOtherFolderId( | |
373 JNIEnv* env, | |
374 const JavaParamRef<jobject>& obj) { | |
375 const BookmarkNode* other_node = bookmark_model_->other_node(); | |
376 ScopedJavaLocalRef<jobject> folder_id_obj = | |
377 JavaBookmarkIdCreateBookmarkId( | |
378 env, other_node->id(), GetBookmarkType(other_node)); | |
379 return folder_id_obj; | |
380 } | |
381 | |
382 ScopedJavaLocalRef<jobject> BookmarksBridge::GetDesktopFolderId( | |
383 JNIEnv* env, | |
384 const JavaParamRef<jobject>& obj) { | |
385 const BookmarkNode* desktop_node = bookmark_model_->bookmark_bar_node(); | |
386 ScopedJavaLocalRef<jobject> folder_id_obj = | |
387 JavaBookmarkIdCreateBookmarkId( | |
388 env, desktop_node->id(), GetBookmarkType(desktop_node)); | |
389 return folder_id_obj; | |
390 } | |
391 | |
392 jint BookmarksBridge::GetChildCount(JNIEnv* env, | |
393 const JavaParamRef<jobject>& obj, | |
394 jlong id, | |
395 jint type) { | |
396 DCHECK(IsLoaded()); | |
397 const BookmarkNode* node = GetNodeByID(id, type); | |
398 return node->child_count(); | |
399 } | |
400 | |
401 void BookmarksBridge::GetChildIDs(JNIEnv* env, | |
402 const JavaParamRef<jobject>& obj, | |
403 jlong id, | |
404 jint type, | |
405 jboolean get_folders, | |
406 jboolean get_bookmarks, | |
407 const JavaParamRef<jobject>& j_result_obj) { | |
408 DCHECK(IsLoaded()); | |
409 | |
410 const BookmarkNode* parent = GetNodeByID(id, type); | |
411 if (!parent->is_folder() || !IsReachable(parent)) | |
412 return; | |
413 | |
414 // Get the folder contents | |
415 for (int i = 0; i < parent->child_count(); ++i) { | |
416 const BookmarkNode* child = parent->GetChild(i); | |
417 if (!IsFolderAvailable(child) || !IsReachable(child)) | |
418 continue; | |
419 | |
420 if ((child->is_folder() && get_folders) || | |
421 (!child->is_folder() && get_bookmarks)) { | |
422 Java_BookmarksBridge_addToBookmarkIdList( | |
423 env, j_result_obj, child->id(), GetBookmarkType(child)); | |
424 } | |
425 } | |
426 | |
427 // Partner bookmark root node is under mobile node. | |
428 if (parent == bookmark_model_->mobile_node() && get_folders && | |
429 partner_bookmarks_shim_->HasPartnerBookmarks() && | |
430 IsReachable(partner_bookmarks_shim_->GetPartnerBookmarksRoot())) { | |
431 Java_BookmarksBridge_addToBookmarkIdList( | |
432 env, | |
433 j_result_obj, | |
434 partner_bookmarks_shim_->GetPartnerBookmarksRoot()->id(), | |
435 BookmarkType::BOOKMARK_TYPE_PARTNER); | |
436 } | |
437 } | |
438 | |
439 ScopedJavaLocalRef<jobject> BookmarksBridge::GetChildAt( | |
440 JNIEnv* env, | |
441 const JavaParamRef<jobject>& obj, | |
442 jlong id, | |
443 jint type, | |
444 jint index) { | |
445 DCHECK(IsLoaded()); | |
446 | |
447 const BookmarkNode* parent = GetNodeByID(id, type); | |
448 DCHECK(parent); | |
449 const BookmarkNode* child = parent->GetChild(index); | |
450 return JavaBookmarkIdCreateBookmarkId( | |
451 env, child->id(), GetBookmarkType(child)); | |
452 } | |
453 | |
454 void BookmarksBridge::GetAllBookmarkIDsOrderedByCreationDate( | |
455 JNIEnv* env, | |
456 const JavaParamRef<jobject>& obj, | |
457 const JavaParamRef<jobject>& j_result_obj) { | |
458 DCHECK(IsLoaded()); | |
459 std::list<const BookmarkNode*> folders; | |
460 std::vector<const BookmarkNode*> result; | |
461 folders.push_back(bookmark_model_->root_node()); | |
462 | |
463 for (std::list<const BookmarkNode*>::iterator folder_iter = folders.begin(); | |
464 folder_iter != folders.end(); ++folder_iter) { | |
465 if (*folder_iter == NULL) | |
466 continue; | |
467 | |
468 std::list<const BookmarkNode*>::iterator insert_iter = folder_iter; | |
469 ++insert_iter; | |
470 | |
471 for (int i = 0; i < (*folder_iter)->child_count(); ++i) { | |
472 const BookmarkNode* child = (*folder_iter)->GetChild(i); | |
473 if (!IsReachable(child) || | |
474 bookmarks::IsDescendantOf( | |
475 child, managed_bookmark_service_->managed_node()) || | |
476 bookmarks::IsDescendantOf( | |
477 child, managed_bookmark_service_->supervised_node())) { | |
478 continue; | |
479 } | |
480 | |
481 if (child->is_folder()) { | |
482 insert_iter = folders.insert(insert_iter, child); | |
483 } else { | |
484 result.push_back(child); | |
485 } | |
486 } | |
487 } | |
488 | |
489 std::sort( | |
490 result.begin(), result.end(), BookmarkNodeCreationTimeCompareFunctor()); | |
491 | |
492 for (std::vector<const BookmarkNode*>::const_iterator iter = result.begin(); | |
493 iter != result.end(); | |
494 ++iter) { | |
495 const BookmarkNode* bookmark = *iter; | |
496 Java_BookmarksBridge_addToBookmarkIdList( | |
497 env, j_result_obj, bookmark->id(), GetBookmarkType(bookmark)); | |
498 } | |
499 } | |
500 | |
501 void BookmarksBridge::SetBookmarkTitle(JNIEnv* env, | |
502 const JavaParamRef<jobject>& obj, | |
503 jlong id, | |
504 jint type, | |
505 const JavaParamRef<jstring>& j_title) { | |
506 DCHECK(IsLoaded()); | |
507 const BookmarkNode* bookmark = GetNodeByID(id, type); | |
508 const base::string16 title = | |
509 base::android::ConvertJavaStringToUTF16(env, j_title); | |
510 | |
511 if (partner_bookmarks_shim_->IsPartnerBookmark(bookmark)) { | |
512 partner_bookmarks_shim_->RenameBookmark(bookmark, title); | |
513 } else { | |
514 bookmark_model_->SetTitle(bookmark, title); | |
515 } | |
516 } | |
517 | |
518 void BookmarksBridge::SetBookmarkUrl(JNIEnv* env, | |
519 const JavaParamRef<jobject>& obj, | |
520 jlong id, | |
521 jint type, | |
522 const JavaParamRef<jstring>& url) { | |
523 DCHECK(IsLoaded()); | |
524 bookmark_model_->SetURL( | |
525 GetNodeByID(id, type), | |
526 GURL(base::android::ConvertJavaStringToUTF16(env, url))); | |
527 } | |
528 | |
529 bool BookmarksBridge::DoesBookmarkExist(JNIEnv* env, | |
530 const JavaParamRef<jobject>& obj, | |
531 jlong id, | |
532 jint type) { | |
533 DCHECK(IsLoaded()); | |
534 | |
535 const BookmarkNode* node = GetNodeByID(id, type); | |
536 | |
537 if (!node) | |
538 return false; | |
539 | |
540 if (type == BookmarkType::BOOKMARK_TYPE_NORMAL) { | |
541 return true; | |
542 } else { | |
543 DCHECK(type == BookmarkType::BOOKMARK_TYPE_PARTNER); | |
544 return partner_bookmarks_shim_->IsReachable(node); | |
545 } | |
546 } | |
547 | |
548 void BookmarksBridge::GetBookmarksForFolder( | |
549 JNIEnv* env, | |
550 const JavaParamRef<jobject>& obj, | |
551 const JavaParamRef<jobject>& j_folder_id_obj, | |
552 const JavaParamRef<jobject>& j_callback_obj, | |
553 const JavaParamRef<jobject>& j_result_obj) { | |
554 DCHECK(IsLoaded()); | |
555 long folder_id = JavaBookmarkIdGetId(env, j_folder_id_obj); | |
556 int type = JavaBookmarkIdGetType(env, j_folder_id_obj); | |
557 const BookmarkNode* folder = GetFolderWithFallback(folder_id, type); | |
558 | |
559 if (!folder->is_folder() || !IsReachable(folder)) | |
560 return; | |
561 | |
562 // Recreate the java bookmarkId object due to fallback. | |
563 ScopedJavaLocalRef<jobject> folder_id_obj = | |
564 JavaBookmarkIdCreateBookmarkId( | |
565 env, folder->id(), GetBookmarkType(folder)); | |
566 | |
567 // Get the folder contents. | |
568 for (int i = 0; i < folder->child_count(); ++i) { | |
569 const BookmarkNode* node = folder->GetChild(i); | |
570 if (!IsFolderAvailable(node)) | |
571 continue; | |
572 ExtractBookmarkNodeInformation(node, j_result_obj); | |
573 } | |
574 | |
575 if (folder == bookmark_model_->mobile_node() && | |
576 partner_bookmarks_shim_->HasPartnerBookmarks()) { | |
577 ExtractBookmarkNodeInformation( | |
578 partner_bookmarks_shim_->GetPartnerBookmarksRoot(), | |
579 j_result_obj); | |
580 } | |
581 | |
582 if (j_callback_obj) { | |
583 Java_BookmarksCallback_onBookmarksAvailable( | |
584 env, j_callback_obj, folder_id_obj.obj(), j_result_obj); | |
585 } | |
586 } | |
587 | |
588 jboolean BookmarksBridge::IsFolderVisible(JNIEnv* env, | |
589 const JavaParamRef<jobject>& obj, | |
590 jlong id, | |
591 jint type) { | |
592 if (type == BookmarkType::BOOKMARK_TYPE_NORMAL) { | |
593 const BookmarkNode* node = bookmarks::GetBookmarkNodeByID( | |
594 bookmark_model_, static_cast<int64_t>(id)); | |
595 return node->IsVisible(); | |
596 } else if (type == BookmarkType::BOOKMARK_TYPE_PARTNER) { | |
597 const BookmarkNode* node = partner_bookmarks_shim_->GetNodeByID( | |
598 static_cast<long>(id)); | |
599 return partner_bookmarks_shim_->IsReachable(node); | |
600 } | |
601 | |
602 NOTREACHED(); | |
603 return false; | |
604 } | |
605 | |
606 void BookmarksBridge::GetCurrentFolderHierarchy( | |
607 JNIEnv* env, | |
608 const JavaParamRef<jobject>& obj, | |
609 const JavaParamRef<jobject>& j_folder_id_obj, | |
610 const JavaParamRef<jobject>& j_callback_obj, | |
611 const JavaParamRef<jobject>& j_result_obj) { | |
612 DCHECK(IsLoaded()); | |
613 long folder_id = JavaBookmarkIdGetId(env, j_folder_id_obj); | |
614 int type = JavaBookmarkIdGetType(env, j_folder_id_obj); | |
615 const BookmarkNode* folder = GetFolderWithFallback(folder_id, type); | |
616 | |
617 if (!folder->is_folder() || !IsReachable(folder)) | |
618 return; | |
619 | |
620 // Recreate the java bookmarkId object due to fallback. | |
621 ScopedJavaLocalRef<jobject> folder_id_obj = | |
622 JavaBookmarkIdCreateBookmarkId( | |
623 env, folder->id(), GetBookmarkType(folder)); | |
624 | |
625 // Get the folder hierarchy. | |
626 const BookmarkNode* node = folder; | |
627 while (node) { | |
628 ExtractBookmarkNodeInformation(node, j_result_obj); | |
629 node = GetParentNode(node); | |
630 } | |
631 | |
632 Java_BookmarksCallback_onBookmarksFolderHierarchyAvailable( | |
633 env, j_callback_obj, folder_id_obj.obj(), j_result_obj); | |
634 } | |
635 | |
636 void BookmarksBridge::SearchBookmarks(JNIEnv* env, | |
637 const JavaParamRef<jobject>& obj, | |
638 const JavaParamRef<jobject>& j_list, | |
639 const JavaParamRef<jstring>& j_query, | |
640 jint max_results) { | |
641 DCHECK(bookmark_model_->loaded()); | |
642 | |
643 std::vector<bookmarks::BookmarkMatch> results; | |
644 bookmark_model_->GetBookmarksMatching( | |
645 base::android::ConvertJavaStringToUTF16(env, j_query), | |
646 max_results, | |
647 query_parser::MatchingAlgorithm::ALWAYS_PREFIX_SEARCH, | |
648 &results); | |
649 for (const bookmarks::BookmarkMatch& match : results) { | |
650 const BookmarkNode* node = match.node; | |
651 | |
652 std::vector<int> title_match_start_positions; | |
653 std::vector<int> title_match_end_positions; | |
654 for (auto position : match.title_match_positions) { | |
655 title_match_start_positions.push_back(position.first); | |
656 title_match_end_positions.push_back(position.second); | |
657 } | |
658 | |
659 std::vector<int> url_match_start_positions; | |
660 std::vector<int> url_match_end_positions; | |
661 for (auto position : match.url_match_positions) { | |
662 url_match_start_positions.push_back(position.first); | |
663 url_match_end_positions.push_back(position.second); | |
664 } | |
665 | |
666 Java_BookmarksBridge_addToBookmarkMatchList( | |
667 env, j_list, node->id(), node->type(), | |
668 ToJavaIntArray(env, title_match_start_positions).obj(), | |
669 ToJavaIntArray(env, title_match_end_positions).obj(), | |
670 ToJavaIntArray(env, url_match_start_positions).obj(), | |
671 ToJavaIntArray(env, url_match_end_positions).obj()); | |
672 } | |
673 } | |
674 | |
675 ScopedJavaLocalRef<jobject> BookmarksBridge::AddFolder( | |
676 JNIEnv* env, | |
677 const JavaParamRef<jobject>& obj, | |
678 const JavaParamRef<jobject>& j_parent_id_obj, | |
679 jint index, | |
680 const JavaParamRef<jstring>& j_title) { | |
681 DCHECK(IsLoaded()); | |
682 long bookmark_id = JavaBookmarkIdGetId(env, j_parent_id_obj); | |
683 int type = JavaBookmarkIdGetType(env, j_parent_id_obj); | |
684 const BookmarkNode* parent = GetNodeByID(bookmark_id, type); | |
685 | |
686 const BookmarkNode* new_node = bookmark_model_->AddFolder( | |
687 parent, index, base::android::ConvertJavaStringToUTF16(env, j_title)); | |
688 if (!new_node) { | |
689 NOTREACHED(); | |
690 return ScopedJavaLocalRef<jobject>(); | |
691 } | |
692 ScopedJavaLocalRef<jobject> new_java_obj = | |
693 JavaBookmarkIdCreateBookmarkId( | |
694 env, new_node->id(), GetBookmarkType(new_node)); | |
695 return new_java_obj; | |
696 } | |
697 | |
698 void BookmarksBridge::DeleteBookmark( | |
699 JNIEnv* env, | |
700 const JavaParamRef<jobject>& obj, | |
701 const JavaParamRef<jobject>& j_bookmark_id_obj) { | |
702 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
703 DCHECK(IsLoaded()); | |
704 | |
705 long bookmark_id = JavaBookmarkIdGetId(env, j_bookmark_id_obj); | |
706 int type = JavaBookmarkIdGetType(env, j_bookmark_id_obj); | |
707 const BookmarkNode* node = GetNodeByID(bookmark_id, type); | |
708 if (!IsEditable(node)) { | |
709 NOTREACHED(); | |
710 return; | |
711 } | |
712 | |
713 if (partner_bookmarks_shim_->IsPartnerBookmark(node)) | |
714 partner_bookmarks_shim_->RemoveBookmark(node); | |
715 else | |
716 bookmark_model_->Remove(node); | |
717 } | |
718 | |
719 void BookmarksBridge::MoveBookmark( | |
720 JNIEnv* env, | |
721 const JavaParamRef<jobject>& obj, | |
722 const JavaParamRef<jobject>& j_bookmark_id_obj, | |
723 const JavaParamRef<jobject>& j_parent_id_obj, | |
724 jint index) { | |
725 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
726 DCHECK(IsLoaded()); | |
727 | |
728 long bookmark_id = JavaBookmarkIdGetId(env, j_bookmark_id_obj); | |
729 int type = JavaBookmarkIdGetType(env, j_bookmark_id_obj); | |
730 const BookmarkNode* node = GetNodeByID(bookmark_id, type); | |
731 if (!IsEditable(node)) { | |
732 NOTREACHED(); | |
733 return; | |
734 } | |
735 bookmark_id = JavaBookmarkIdGetId(env, j_parent_id_obj); | |
736 type = JavaBookmarkIdGetType(env, j_parent_id_obj); | |
737 const BookmarkNode* new_parent_node = GetNodeByID(bookmark_id, type); | |
738 bookmark_model_->Move(node, new_parent_node, index); | |
739 } | |
740 | |
741 ScopedJavaLocalRef<jobject> BookmarksBridge::AddBookmark( | |
742 JNIEnv* env, | |
743 const JavaParamRef<jobject>& obj, | |
744 const JavaParamRef<jobject>& j_parent_id_obj, | |
745 jint index, | |
746 const JavaParamRef<jstring>& j_title, | |
747 const JavaParamRef<jstring>& j_url) { | |
748 DCHECK(IsLoaded()); | |
749 long bookmark_id = JavaBookmarkIdGetId(env, j_parent_id_obj); | |
750 int type = JavaBookmarkIdGetType(env, j_parent_id_obj); | |
751 const BookmarkNode* parent = GetNodeByID(bookmark_id, type); | |
752 | |
753 const BookmarkNode* new_node = bookmark_model_->AddURL( | |
754 parent, | |
755 index, | |
756 base::android::ConvertJavaStringToUTF16(env, j_title), | |
757 GURL(base::android::ConvertJavaStringToUTF16(env, j_url))); | |
758 if (!new_node) { | |
759 NOTREACHED(); | |
760 return ScopedJavaLocalRef<jobject>(); | |
761 } | |
762 ScopedJavaLocalRef<jobject> new_java_obj = | |
763 JavaBookmarkIdCreateBookmarkId( | |
764 env, new_node->id(), GetBookmarkType(new_node)); | |
765 return new_java_obj; | |
766 } | |
767 | |
768 void BookmarksBridge::Undo(JNIEnv* env, const JavaParamRef<jobject>& obj) { | |
769 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
770 DCHECK(IsLoaded()); | |
771 BookmarkUndoService* undo_service = | |
772 BookmarkUndoServiceFactory::GetForProfile(profile_); | |
773 UndoManager* undo_manager = undo_service->undo_manager(); | |
774 undo_manager->Undo(); | |
775 } | |
776 | |
777 void BookmarksBridge::StartGroupingUndos(JNIEnv* env, | |
778 const JavaParamRef<jobject>& obj) { | |
779 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
780 DCHECK(IsLoaded()); | |
781 DCHECK(!grouped_bookmark_actions_.get()); // shouldn't have started already | |
782 grouped_bookmark_actions_.reset( | |
783 new bookmarks::ScopedGroupBookmarkActions(bookmark_model_)); | |
784 } | |
785 | |
786 void BookmarksBridge::EndGroupingUndos(JNIEnv* env, | |
787 const JavaParamRef<jobject>& obj) { | |
788 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
789 DCHECK(IsLoaded()); | |
790 DCHECK(grouped_bookmark_actions_.get()); // should only call after start | |
791 grouped_bookmark_actions_.reset(); | |
792 } | |
793 | |
794 base::string16 BookmarksBridge::GetTitle(const BookmarkNode* node) const { | |
795 if (partner_bookmarks_shim_->IsPartnerBookmark(node)) | |
796 return partner_bookmarks_shim_->GetTitle(node); | |
797 | |
798 return node->GetTitle(); | |
799 } | |
800 | |
801 ScopedJavaLocalRef<jobject> BookmarksBridge::CreateJavaBookmark( | |
802 const BookmarkNode* node) { | |
803 JNIEnv* env = AttachCurrentThread(); | |
804 | |
805 const BookmarkNode* parent = GetParentNode(node); | |
806 int64_t parent_id = parent ? parent->id() : -1; | |
807 | |
808 std::string url; | |
809 if (node->is_url()) | |
810 url = node->url().spec(); | |
811 | |
812 return Java_BookmarksBridge_createBookmarkItem( | |
813 env, | |
814 node->id(), | |
815 GetBookmarkType(node), | |
816 ConvertUTF16ToJavaString(env, GetTitle(node)).obj(), | |
817 ConvertUTF8ToJavaString(env, url).obj(), | |
818 node->is_folder(), | |
819 parent_id, | |
820 GetBookmarkType(parent), | |
821 IsEditable(node), | |
822 IsManaged(node)); | |
823 } | |
824 | |
825 void BookmarksBridge::ExtractBookmarkNodeInformation(const BookmarkNode* node, | |
826 jobject j_result_obj) { | |
827 JNIEnv* env = AttachCurrentThread(); | |
828 if (!IsReachable(node)) | |
829 return; | |
830 Java_BookmarksBridge_addToList( | |
831 env, j_result_obj, CreateJavaBookmark(node).obj()); | |
832 } | |
833 | |
834 const BookmarkNode* BookmarksBridge::GetNodeByID(long node_id, int type) { | |
835 const BookmarkNode* node; | |
836 if (type == BookmarkType::BOOKMARK_TYPE_PARTNER) { | |
837 node = partner_bookmarks_shim_->GetNodeByID(static_cast<int64_t>(node_id)); | |
838 } else { | |
839 node = bookmarks::GetBookmarkNodeByID(bookmark_model_, | |
840 static_cast<int64_t>(node_id)); | |
841 } | |
842 return node; | |
843 } | |
844 | |
845 const BookmarkNode* BookmarksBridge::GetFolderWithFallback(long folder_id, | |
846 int type) { | |
847 const BookmarkNode* folder = GetNodeByID(folder_id, type); | |
848 if (!folder || folder->type() == BookmarkNode::URL || | |
849 !IsFolderAvailable(folder)) { | |
850 if (!managed_bookmark_service_->managed_node()->empty()) | |
851 folder = managed_bookmark_service_->managed_node(); | |
852 else | |
853 folder = bookmark_model_->mobile_node(); | |
854 } | |
855 return folder; | |
856 } | |
857 | |
858 bool BookmarksBridge::IsEditBookmarksEnabled() const { | |
859 return profile_->GetPrefs()->GetBoolean( | |
860 bookmarks::prefs::kEditBookmarksEnabled); | |
861 } | |
862 | |
863 void BookmarksBridge::EditBookmarksEnabledChanged() { | |
864 JNIEnv* env = AttachCurrentThread(); | |
865 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
866 if (obj.is_null()) | |
867 return; | |
868 Java_BookmarksBridge_editBookmarksEnabledChanged(env, obj.obj()); | |
869 } | |
870 | |
871 bool BookmarksBridge::IsEditable(const BookmarkNode* node) const { | |
872 if (!node || (node->type() != BookmarkNode::FOLDER && | |
873 node->type() != BookmarkNode::URL)) { | |
874 return false; | |
875 } | |
876 if (!IsEditBookmarksEnabled()) | |
877 return false; | |
878 if (partner_bookmarks_shim_->IsPartnerBookmark(node)) | |
879 return partner_bookmarks_shim_->IsEditable(node); | |
880 return managed_bookmark_service_->CanBeEditedByUser(node); | |
881 } | |
882 | |
883 bool BookmarksBridge::IsManaged(const BookmarkNode* node) const { | |
884 return bookmarks::IsDescendantOf(node, | |
885 managed_bookmark_service_->managed_node()); | |
886 } | |
887 | |
888 const BookmarkNode* BookmarksBridge::GetParentNode(const BookmarkNode* node) { | |
889 DCHECK(IsLoaded()); | |
890 if (node == partner_bookmarks_shim_->GetPartnerBookmarksRoot()) { | |
891 return bookmark_model_->mobile_node(); | |
892 } else { | |
893 return node->parent(); | |
894 } | |
895 } | |
896 | |
897 int BookmarksBridge::GetBookmarkType(const BookmarkNode* node) { | |
898 if (partner_bookmarks_shim_->IsPartnerBookmark(node)) | |
899 return BookmarkType::BOOKMARK_TYPE_PARTNER; | |
900 else | |
901 return BookmarkType::BOOKMARK_TYPE_NORMAL; | |
902 } | |
903 | |
904 bool BookmarksBridge::IsReachable(const BookmarkNode* node) const { | |
905 if (!partner_bookmarks_shim_->IsPartnerBookmark(node)) | |
906 return true; | |
907 return partner_bookmarks_shim_->IsReachable(node); | |
908 } | |
909 | |
910 bool BookmarksBridge::IsLoaded() const { | |
911 return (bookmark_model_->loaded() && partner_bookmarks_shim_->IsLoaded()); | |
912 } | |
913 | |
914 bool BookmarksBridge::IsFolderAvailable( | |
915 const BookmarkNode* folder) const { | |
916 // The managed bookmarks folder is not shown if there are no bookmarks | |
917 // configured via policy. | |
918 if (folder == managed_bookmark_service_->managed_node() && folder->empty()) | |
919 return false; | |
920 // Similarly, the supervised bookmarks folder is not shown if there are no | |
921 // bookmarks configured by the custodian. | |
922 if (folder == managed_bookmark_service_->supervised_node() && folder->empty()) | |
923 return false; | |
924 | |
925 SigninManager* signin = SigninManagerFactory::GetForProfile( | |
926 profile_->GetOriginalProfile()); | |
927 return (folder->type() != BookmarkNode::BOOKMARK_BAR && | |
928 folder->type() != BookmarkNode::OTHER_NODE) || | |
929 (signin && signin->IsAuthenticated()); | |
930 } | |
931 | |
932 void BookmarksBridge::NotifyIfDoneLoading() { | |
933 if (!IsLoaded()) | |
934 return; | |
935 JNIEnv* env = AttachCurrentThread(); | |
936 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
937 if (obj.is_null()) | |
938 return; | |
939 Java_BookmarksBridge_bookmarkModelLoaded(env, obj.obj()); | |
940 } | |
941 | |
942 // ------------- Observer-related methods ------------- // | |
943 | |
944 void BookmarksBridge::BookmarkModelChanged() { | |
945 if (!IsLoaded()) | |
946 return; | |
947 | |
948 // Called when there are changes to the bookmark model. It is most | |
949 // likely changes to the partner bookmarks. | |
950 JNIEnv* env = AttachCurrentThread(); | |
951 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
952 if (obj.is_null()) | |
953 return; | |
954 Java_BookmarksBridge_bookmarkModelChanged(env, obj.obj()); | |
955 } | |
956 | |
957 void BookmarksBridge::BookmarkModelLoaded(BookmarkModel* model, | |
958 bool ids_reassigned) { | |
959 NotifyIfDoneLoading(); | |
960 } | |
961 | |
962 void BookmarksBridge::BookmarkModelBeingDeleted(BookmarkModel* model) { | |
963 if (!IsLoaded()) | |
964 return; | |
965 | |
966 JNIEnv* env = AttachCurrentThread(); | |
967 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
968 if (obj.is_null()) | |
969 return; | |
970 Java_BookmarksBridge_bookmarkModelDeleted(env, obj.obj()); | |
971 } | |
972 | |
973 void BookmarksBridge::BookmarkNodeMoved(BookmarkModel* model, | |
974 const BookmarkNode* old_parent, | |
975 int old_index, | |
976 const BookmarkNode* new_parent, | |
977 int new_index) { | |
978 if (!IsLoaded()) | |
979 return; | |
980 | |
981 JNIEnv* env = AttachCurrentThread(); | |
982 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
983 if (obj.is_null()) | |
984 return; | |
985 Java_BookmarksBridge_bookmarkNodeMoved( | |
986 env, | |
987 obj.obj(), | |
988 CreateJavaBookmark(old_parent).obj(), | |
989 old_index, | |
990 CreateJavaBookmark(new_parent).obj(), | |
991 new_index); | |
992 } | |
993 | |
994 void BookmarksBridge::BookmarkNodeAdded(BookmarkModel* model, | |
995 const BookmarkNode* parent, | |
996 int index) { | |
997 if (!IsLoaded()) | |
998 return; | |
999 | |
1000 JNIEnv* env = AttachCurrentThread(); | |
1001 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
1002 if (obj.is_null()) | |
1003 return; | |
1004 Java_BookmarksBridge_bookmarkNodeAdded( | |
1005 env, | |
1006 obj.obj(), | |
1007 CreateJavaBookmark(parent).obj(), | |
1008 index); | |
1009 } | |
1010 | |
1011 void BookmarksBridge::BookmarkNodeRemoved(BookmarkModel* model, | |
1012 const BookmarkNode* parent, | |
1013 int old_index, | |
1014 const BookmarkNode* node, | |
1015 const std::set<GURL>& removed_urls) { | |
1016 if (!IsLoaded()) | |
1017 return; | |
1018 | |
1019 JNIEnv* env = AttachCurrentThread(); | |
1020 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
1021 if (obj.is_null()) | |
1022 return; | |
1023 Java_BookmarksBridge_bookmarkNodeRemoved( | |
1024 env, | |
1025 obj.obj(), | |
1026 CreateJavaBookmark(parent).obj(), | |
1027 old_index, | |
1028 CreateJavaBookmark(node).obj()); | |
1029 } | |
1030 | |
1031 void BookmarksBridge::BookmarkAllUserNodesRemoved( | |
1032 BookmarkModel* model, | |
1033 const std::set<GURL>& removed_urls) { | |
1034 if (!IsLoaded()) | |
1035 return; | |
1036 | |
1037 JNIEnv* env = AttachCurrentThread(); | |
1038 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
1039 if (obj.is_null()) | |
1040 return; | |
1041 Java_BookmarksBridge_bookmarkAllUserNodesRemoved(env, obj.obj()); | |
1042 } | |
1043 | |
1044 void BookmarksBridge::BookmarkNodeChanged(BookmarkModel* model, | |
1045 const BookmarkNode* node) { | |
1046 if (!IsLoaded()) | |
1047 return; | |
1048 | |
1049 JNIEnv* env = AttachCurrentThread(); | |
1050 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
1051 if (obj.is_null()) | |
1052 return; | |
1053 Java_BookmarksBridge_bookmarkNodeChanged( | |
1054 env, | |
1055 obj.obj(), | |
1056 CreateJavaBookmark(node).obj()); | |
1057 } | |
1058 | |
1059 void BookmarksBridge::BookmarkNodeChildrenReordered(BookmarkModel* model, | |
1060 const BookmarkNode* node) { | |
1061 if (!IsLoaded()) | |
1062 return; | |
1063 | |
1064 JNIEnv* env = AttachCurrentThread(); | |
1065 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
1066 if (obj.is_null()) | |
1067 return; | |
1068 Java_BookmarksBridge_bookmarkNodeChildrenReordered( | |
1069 env, | |
1070 obj.obj(), | |
1071 CreateJavaBookmark(node).obj()); | |
1072 } | |
1073 | |
1074 void BookmarksBridge::ExtensiveBookmarkChangesBeginning(BookmarkModel* model) { | |
1075 if (!IsLoaded()) | |
1076 return; | |
1077 | |
1078 JNIEnv* env = AttachCurrentThread(); | |
1079 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
1080 if (obj.is_null()) | |
1081 return; | |
1082 Java_BookmarksBridge_extensiveBookmarkChangesBeginning(env, obj.obj()); | |
1083 } | |
1084 | |
1085 void BookmarksBridge::ExtensiveBookmarkChangesEnded(BookmarkModel* model) { | |
1086 if (!IsLoaded()) | |
1087 return; | |
1088 | |
1089 JNIEnv* env = AttachCurrentThread(); | |
1090 ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env); | |
1091 if (obj.is_null()) | |
1092 return; | |
1093 Java_BookmarksBridge_extensiveBookmarkChangesEnded(env, obj.obj()); | |
1094 } | |
1095 | |
1096 void BookmarksBridge::PartnerShimChanged(PartnerBookmarksShim* shim) { | |
1097 if (!IsLoaded()) | |
1098 return; | |
1099 | |
1100 BookmarkModelChanged(); | |
1101 } | |
1102 | |
1103 void BookmarksBridge::PartnerShimLoaded(PartnerBookmarksShim* shim) { | |
1104 NotifyIfDoneLoading(); | |
1105 } | |
1106 | |
1107 void BookmarksBridge::ShimBeingDeleted(PartnerBookmarksShim* shim) { | |
1108 partner_bookmarks_shim_ = NULL; | |
1109 } | |
OLD | NEW |