OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/provider/chrome_browser_provider.h" | 5 #include "chrome/browser/android/provider/chrome_browser_provider.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <cmath> | 9 #include <cmath> |
10 #include <list> | 10 #include <list> |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 // from the UI thread, but RunOnUIThread can be safely used from the UI | 80 // from the UI thread, but RunOnUIThread can be safely used from the UI |
81 // thread code of other BookmarkModelTasks. | 81 // thread code of other BookmarkModelTasks. |
82 // | 82 // |
83 // - AsyncServiceRequest: base class for any asynchronous requests made to a | 83 // - AsyncServiceRequest: base class for any asynchronous requests made to a |
84 // Chromium service that require to block the current thread until completed. | 84 // Chromium service that require to block the current thread until completed. |
85 // Derived classes should make use of RunAsyncRequestOnUIThreadBlocking to | 85 // Derived classes should make use of RunAsyncRequestOnUIThreadBlocking to |
86 // post their requests in the UI thread and return the results synchronously. | 86 // post their requests in the UI thread and return the results synchronously. |
87 // All derived classes MUST ALWAYS call RequestCompleted when receiving the | 87 // All derived classes MUST ALWAYS call RequestCompleted when receiving the |
88 // request response. These tasks cannot be invoked from the UI thread. | 88 // request response. These tasks cannot be invoked from the UI thread. |
89 // | 89 // |
90 // - FaviconServiceTask: base class for asynchronous requests that make use of | |
91 // Chromium's favicon service. See AsyncServiceRequest for more details. | |
92 // | |
93 // - HistoryProviderTask: base class for asynchronous requests that make use of | 90 // - HistoryProviderTask: base class for asynchronous requests that make use of |
94 // AndroidHistoryProviderService. See AsyncServiceRequest for mode details. | 91 // AndroidHistoryProviderService. See AsyncServiceRequest for mode details. |
95 // | 92 // |
96 // - SearchTermTask: base class for asynchronous requests that involve the | 93 // - SearchTermTask: base class for asynchronous requests that involve the |
97 // search term API. Works in the same way as HistoryProviderTask. | 94 // search term API. Works in the same way as HistoryProviderTask. |
98 | 95 |
99 namespace { | 96 namespace { |
100 | 97 |
101 const char kDefaultUrlScheme[] = "http://"; | 98 const char kDefaultUrlScheme[] = "http://"; |
102 const int64_t kInvalidContentProviderId = 0; | 99 const int64_t kInvalidContentProviderId = 0; |
103 const int64_t kInvalidBookmarkId = -1; | 100 const int64_t kInvalidBookmarkId = -1; |
104 | 101 |
105 // ------------- Java-related utility methods ------------- // | 102 // ------------- Java-related utility methods ------------- // |
106 | 103 |
107 // Convert a BookmarkNode, |node|, to the java representation of a bookmark node | |
108 // stored in |*jnode|. Parent node information is optional. | |
109 void ConvertBookmarkNode( | |
110 const BookmarkNode* node, | |
111 const JavaRef<jobject>& parent_node, | |
112 ScopedJavaGlobalRef<jobject>* jnode) { | |
113 DCHECK(jnode); | |
114 if (!node) | |
115 return; | |
116 | |
117 JNIEnv* env = AttachCurrentThread(); | |
118 ScopedJavaLocalRef<jstring> url; | |
119 if (node->is_url()) | |
120 url.Reset(ConvertUTF8ToJavaString(env, node->url().spec())); | |
121 ScopedJavaLocalRef<jstring> title( | |
122 ConvertUTF16ToJavaString(env, node->GetTitle())); | |
123 | |
124 jnode->Reset( | |
125 Java_BookmarkNode_create( | |
126 env, node->id(), (jint) node->type(), title.obj(), url.obj(), | |
127 parent_node.obj())); | |
128 } | |
129 | |
130 jlong ConvertJLongObjectToPrimitive(JNIEnv* env, jobject long_obj) { | 104 jlong ConvertJLongObjectToPrimitive(JNIEnv* env, jobject long_obj) { |
131 ScopedJavaLocalRef<jclass> jlong_clazz = GetClass(env, "java/lang/Long"); | 105 ScopedJavaLocalRef<jclass> jlong_clazz = GetClass(env, "java/lang/Long"); |
132 jmethodID long_value = MethodID::Get<MethodID::TYPE_INSTANCE>( | 106 jmethodID long_value = MethodID::Get<MethodID::TYPE_INSTANCE>( |
133 env, jlong_clazz.obj(), "longValue", "()J"); | 107 env, jlong_clazz.obj(), "longValue", "()J"); |
134 return env->CallLongMethod(long_obj, long_value, NULL); | 108 return env->CallLongMethod(long_obj, long_value, NULL); |
135 } | 109 } |
136 | 110 |
137 jboolean ConvertJBooleanObjectToPrimitive(JNIEnv* env, jobject boolean_object) { | 111 jboolean ConvertJBooleanObjectToPrimitive(JNIEnv* env, jobject boolean_object) { |
138 ScopedJavaLocalRef<jclass> jboolean_clazz = | 112 ScopedJavaLocalRef<jclass> jboolean_clazz = |
139 GetClass(env, "java/lang/Boolean"); | 113 GetClass(env, "java/lang/Boolean"); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 const char* default_scheme) { | 151 const char* default_scheme) { |
178 GURL gurl(url); | 152 GURL gurl(url); |
179 if (!gurl.is_valid() && !gurl.has_scheme()) { | 153 if (!gurl.is_valid() && !gurl.has_scheme()) { |
180 base::string16 refined_url(base::ASCIIToUTF16(default_scheme)); | 154 base::string16 refined_url(base::ASCIIToUTF16(default_scheme)); |
181 refined_url.append(url); | 155 refined_url.append(url); |
182 gurl = GURL(refined_url); | 156 gurl = GURL(refined_url); |
183 } | 157 } |
184 return gurl; | 158 return gurl; |
185 } | 159 } |
186 | 160 |
187 const BookmarkNode* GetChildFolderByTitle(const BookmarkNode* parent, | |
188 const base::string16& title) { | |
189 for (int i = 0; i < parent->child_count(); ++i) { | |
190 if (parent->GetChild(i)->is_folder() && | |
191 parent->GetChild(i)->GetTitle() == title) { | |
192 return parent->GetChild(i); | |
193 } | |
194 } | |
195 return NULL; | |
196 } | |
197 | |
198 // ------------- Synchronous task classes ------------- // | 161 // ------------- Synchronous task classes ------------- // |
199 | 162 |
200 // Utility task to add a bookmark. | 163 // Utility task to add a bookmark. |
201 class AddBookmarkTask : public BookmarkModelTask { | 164 class AddBookmarkTask : public BookmarkModelTask { |
202 public: | 165 public: |
203 explicit AddBookmarkTask(BookmarkModel* model) : BookmarkModelTask(model) {} | 166 explicit AddBookmarkTask(BookmarkModel* model) : BookmarkModelTask(model) {} |
204 | 167 |
205 int64_t Run(const base::string16& title, | 168 int64_t Run(const base::string16& title, |
206 const base::string16& url, | 169 const base::string16& url, |
207 const bool is_folder, | 170 const bool is_folder, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 ++deleted_; | 241 ++deleted_; |
279 } | 242 } |
280 | 243 |
281 private: | 244 private: |
282 int deleted_; | 245 int deleted_; |
283 int64_t id_to_delete_; | 246 int64_t id_to_delete_; |
284 | 247 |
285 DISALLOW_COPY_AND_ASSIGN(RemoveBookmarkTask); | 248 DISALLOW_COPY_AND_ASSIGN(RemoveBookmarkTask); |
286 }; | 249 }; |
287 | 250 |
288 // Utility method to remove all bookmarks that the user can edit. | |
289 class RemoveAllUserBookmarksTask : public BookmarkModelObserverTask { | |
290 public: | |
291 explicit RemoveAllUserBookmarksTask(BookmarkModel* model) | |
292 : BookmarkModelObserverTask(model) {} | |
293 | |
294 ~RemoveAllUserBookmarksTask() override {} | |
295 | |
296 void Run() { | |
297 RunOnUIThreadBlocking::Run( | |
298 base::Bind(&RemoveAllUserBookmarksTask::RunOnUIThread, model())); | |
299 } | |
300 | |
301 static void RunOnUIThread(BookmarkModel* model) { | |
302 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
303 LOG(ERROR) << "begin model->RemoveAllUserBookmarks"; | |
304 model->RemoveAllUserBookmarks(); | |
305 LOG(ERROR) << "after model->RemoveAllUserBookmarks"; | |
306 } | |
307 | |
308 private: | |
309 DISALLOW_COPY_AND_ASSIGN(RemoveAllUserBookmarksTask); | |
310 }; | |
311 | |
312 // Utility method to update a bookmark. | 251 // Utility method to update a bookmark. |
313 class UpdateBookmarkTask : public BookmarkModelObserverTask { | 252 class UpdateBookmarkTask : public BookmarkModelObserverTask { |
314 public: | 253 public: |
315 explicit UpdateBookmarkTask(BookmarkModel* model) | 254 explicit UpdateBookmarkTask(BookmarkModel* model) |
316 : BookmarkModelObserverTask(model), | 255 : BookmarkModelObserverTask(model), |
317 updated_(0), | 256 updated_(0), |
318 id_to_update_(kInvalidBookmarkId){} | 257 id_to_update_(kInvalidBookmarkId){} |
319 ~UpdateBookmarkTask() override {} | 258 ~UpdateBookmarkTask() override {} |
320 | 259 |
321 int Run(const int64_t id, | 260 int Run(const int64_t id, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 ++updated_; | 303 ++updated_; |
365 } | 304 } |
366 | 305 |
367 private: | 306 private: |
368 int updated_; | 307 int updated_; |
369 int64_t id_to_update_; | 308 int64_t id_to_update_; |
370 | 309 |
371 DISALLOW_COPY_AND_ASSIGN(UpdateBookmarkTask); | 310 DISALLOW_COPY_AND_ASSIGN(UpdateBookmarkTask); |
372 }; | 311 }; |
373 | 312 |
374 // Checks if a node exists in the bookmark model. | |
375 class BookmarkNodeExistsTask : public BookmarkModelTask { | |
376 public: | |
377 explicit BookmarkNodeExistsTask(BookmarkModel* model) | |
378 : BookmarkModelTask(model) { | |
379 } | |
380 | |
381 bool Run(const int64_t id) { | |
382 bool result = false; | |
383 RunOnUIThreadBlocking::Run( | |
384 base::Bind(&BookmarkNodeExistsTask::RunOnUIThread, | |
385 model(), id, &result)); | |
386 return result; | |
387 } | |
388 | |
389 static void RunOnUIThread(BookmarkModel* model, | |
390 const int64_t id, | |
391 bool* result) { | |
392 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
393 DCHECK(result); | |
394 *result = bookmarks::GetBookmarkNodeByID(model, id) != NULL; | |
395 } | |
396 | |
397 private: | |
398 DISALLOW_COPY_AND_ASSIGN(BookmarkNodeExistsTask); | |
399 }; | |
400 | |
401 // Checks if a node belongs to the Mobile Bookmarks hierarchy branch. | 313 // Checks if a node belongs to the Mobile Bookmarks hierarchy branch. |
402 class IsInMobileBookmarksBranchTask : public BookmarkModelTask { | 314 class IsInMobileBookmarksBranchTask : public BookmarkModelTask { |
403 public: | 315 public: |
404 explicit IsInMobileBookmarksBranchTask(BookmarkModel* model) | 316 explicit IsInMobileBookmarksBranchTask(BookmarkModel* model) |
405 : BookmarkModelTask(model) {} | 317 : BookmarkModelTask(model) {} |
406 | 318 |
407 bool Run(const int64_t id) { | 319 bool Run(const int64_t id) { |
408 bool result = false; | 320 bool result = false; |
409 RunOnUIThreadBlocking::Run( | 321 RunOnUIThreadBlocking::Run( |
410 base::Bind(&IsInMobileBookmarksBranchTask::RunOnUIThread, | 322 base::Bind(&IsInMobileBookmarksBranchTask::RunOnUIThread, |
(...skipping 11 matching lines...) Expand all Loading... |
422 while (node && node != mobile_node) | 334 while (node && node != mobile_node) |
423 node = node->parent(); | 335 node = node->parent(); |
424 | 336 |
425 *result = node == mobile_node; | 337 *result = node == mobile_node; |
426 } | 338 } |
427 | 339 |
428 private: | 340 private: |
429 DISALLOW_COPY_AND_ASSIGN(IsInMobileBookmarksBranchTask); | 341 DISALLOW_COPY_AND_ASSIGN(IsInMobileBookmarksBranchTask); |
430 }; | 342 }; |
431 | 343 |
432 // Creates folder or retrieves its id if already exists. | |
433 // An invalid parent id is assumed to represent the Mobile Bookmarks folder. | |
434 // Can only be used to create folders inside the Mobile Bookmarks branch. | |
435 class CreateBookmarksFolderOnceTask : public BookmarkModelTask { | |
436 public: | |
437 explicit CreateBookmarksFolderOnceTask(BookmarkModel* model) | |
438 : BookmarkModelTask(model) {} | |
439 | |
440 int64_t Run(const base::string16& title, const int64_t parent_id) { | |
441 int64_t result = kInvalidBookmarkId; | |
442 RunOnUIThreadBlocking::Run( | |
443 base::Bind(&CreateBookmarksFolderOnceTask::RunOnUIThread, | |
444 model(), title, parent_id, &result)); | |
445 return result; | |
446 } | |
447 | |
448 static void RunOnUIThread(BookmarkModel* model, | |
449 const base::string16& title, | |
450 const int64_t parent_id, | |
451 int64_t* result) { | |
452 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
453 DCHECK(result); | |
454 | |
455 // Invalid ids are assumed to refer to the Mobile Bookmarks folder. | |
456 const BookmarkNode* parent = | |
457 parent_id >= 0 ? bookmarks::GetBookmarkNodeByID(model, parent_id) | |
458 : model->mobile_node(); | |
459 DCHECK(parent); | |
460 | |
461 bool in_mobile_bookmarks; | |
462 IsInMobileBookmarksBranchTask::RunOnUIThread(model, parent->id(), | |
463 &in_mobile_bookmarks); | |
464 if (!in_mobile_bookmarks) { | |
465 // The parent folder must be inside the Mobile Bookmarks folder. | |
466 *result = kInvalidBookmarkId; | |
467 return; | |
468 } | |
469 | |
470 const BookmarkNode* node = GetChildFolderByTitle(parent, title); | |
471 if (node) { | |
472 *result = node->id(); | |
473 return; | |
474 } | |
475 | |
476 AddBookmarkTask::RunOnUIThread(model, title, base::string16(), true, | |
477 parent->id(), result); | |
478 } | |
479 | |
480 private: | |
481 DISALLOW_COPY_AND_ASSIGN(CreateBookmarksFolderOnceTask); | |
482 }; | |
483 | |
484 // Creates a Java BookmarkNode object for a node given its id. | |
485 class GetEditableBookmarkFoldersTask : public BookmarkModelTask { | |
486 public: | |
487 GetEditableBookmarkFoldersTask( | |
488 ManagedBookmarkService* managed_bookmark_service, | |
489 BookmarkModel* model) | |
490 : BookmarkModelTask(model), | |
491 managed_bookmark_service_(managed_bookmark_service) {} | |
492 | |
493 void Run(ScopedJavaGlobalRef<jobject>* jroot) { | |
494 RunOnUIThreadBlocking::Run( | |
495 base::Bind(&GetEditableBookmarkFoldersTask::RunOnUIThread, | |
496 managed_bookmark_service_, model(), jroot)); | |
497 } | |
498 | |
499 static void RunOnUIThread(ManagedBookmarkService* managed, | |
500 BookmarkModel* model, | |
501 ScopedJavaGlobalRef<jobject>* jroot) { | |
502 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
503 const BookmarkNode* root = model->root_node(); | |
504 if (!root || !root->is_folder()) | |
505 return; | |
506 | |
507 // The iterative approach is not possible because ScopedGlobalJavaRefs | |
508 // cannot be copy-constructed, and therefore not used in STL containers. | |
509 ConvertFolderSubtree(managed, AttachCurrentThread(), root, | |
510 ScopedJavaLocalRef<jobject>(), jroot); | |
511 } | |
512 | |
513 private: | |
514 static void ConvertFolderSubtree(ManagedBookmarkService* managed, | |
515 JNIEnv* env, | |
516 const BookmarkNode* node, | |
517 const JavaRef<jobject>& parent_folder, | |
518 ScopedJavaGlobalRef<jobject>* jfolder) { | |
519 DCHECK(node); | |
520 DCHECK(node->is_folder()); | |
521 DCHECK(jfolder); | |
522 | |
523 // Global refs should be used here for thread-safety reasons as this task | |
524 // might be invoked from a thread other than UI. All refs are scoped. | |
525 ConvertBookmarkNode(node, parent_folder, jfolder); | |
526 | |
527 for (int i = 0; i < node->child_count(); ++i) { | |
528 const BookmarkNode* child = node->GetChild(i); | |
529 if (child->is_folder() && managed->CanBeEditedByUser(child)) { | |
530 ScopedJavaGlobalRef<jobject> jchild; | |
531 ConvertFolderSubtree(managed, env, child, *jfolder, &jchild); | |
532 | |
533 Java_BookmarkNode_addChild(env, jfolder->obj(), jchild.obj()); | |
534 if (ClearException(env)) { | |
535 LOG(WARNING) << "Java exception while adding child node."; | |
536 return; | |
537 } | |
538 } | |
539 } | |
540 } | |
541 | |
542 ManagedBookmarkService* managed_bookmark_service_; | |
543 | |
544 DISALLOW_COPY_AND_ASSIGN(GetEditableBookmarkFoldersTask); | |
545 }; | |
546 | |
547 // Creates a Java BookmarkNode object for a node given its id. | |
548 class GetBookmarkNodeTask : public BookmarkModelTask { | |
549 public: | |
550 explicit GetBookmarkNodeTask(BookmarkModel* model) | |
551 : BookmarkModelTask(model) { | |
552 } | |
553 | |
554 void Run(const int64_t id, | |
555 bool get_parent, | |
556 bool get_children, | |
557 ScopedJavaGlobalRef<jobject>* jnode) { | |
558 return RunOnUIThreadBlocking::Run( | |
559 base::Bind(&GetBookmarkNodeTask::RunOnUIThread, | |
560 model(), id, get_parent, get_children, jnode)); | |
561 } | |
562 | |
563 static void RunOnUIThread(BookmarkModel* model, | |
564 const int64_t id, | |
565 bool get_parent, | |
566 bool get_children, | |
567 ScopedJavaGlobalRef<jobject>* jnode) { | |
568 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
569 const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(model, id); | |
570 if (!node || !jnode) | |
571 return; | |
572 | |
573 ScopedJavaGlobalRef<jobject> jparent; | |
574 if (get_parent) { | |
575 ConvertBookmarkNode(node->parent(), ScopedJavaLocalRef<jobject>(), | |
576 &jparent); | |
577 } | |
578 | |
579 ConvertBookmarkNode(node, jparent, jnode); | |
580 | |
581 JNIEnv* env = AttachCurrentThread(); | |
582 if (!jparent.is_null()) { | |
583 Java_BookmarkNode_addChild(env, jparent.obj(), jnode->obj()); | |
584 if (ClearException(env)) { | |
585 LOG(WARNING) << "Java exception while adding child node."; | |
586 return; | |
587 } | |
588 } | |
589 | |
590 if (get_children) { | |
591 for (int i = 0; i < node->child_count(); ++i) { | |
592 ScopedJavaGlobalRef<jobject> jchild; | |
593 ConvertBookmarkNode(node->GetChild(i), *jnode, &jchild); | |
594 Java_BookmarkNode_addChild(env, jnode->obj(), jchild.obj()); | |
595 if (ClearException(env)) { | |
596 LOG(WARNING) << "Java exception while adding child node."; | |
597 return; | |
598 } | |
599 } | |
600 } | |
601 } | |
602 | |
603 private: | |
604 DISALLOW_COPY_AND_ASSIGN(GetBookmarkNodeTask); | |
605 }; | |
606 | |
607 // Gets the Mobile Bookmarks node. Using this task ensures the correct | |
608 // initialization of the bookmark model. | |
609 class GetMobileBookmarksNodeTask : public BookmarkModelTask { | |
610 public: | |
611 explicit GetMobileBookmarksNodeTask(BookmarkModel* model) | |
612 : BookmarkModelTask(model) {} | |
613 | |
614 const BookmarkNode* Run() { | |
615 const BookmarkNode* result = NULL; | |
616 RunOnUIThreadBlocking::Run( | |
617 base::Bind(&GetMobileBookmarksNodeTask::RunOnUIThread, | |
618 model(), &result)); | |
619 return result; | |
620 } | |
621 | |
622 static void RunOnUIThread(BookmarkModel* model, const BookmarkNode** result) { | |
623 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
624 DCHECK(result); | |
625 *result = model->mobile_node(); | |
626 } | |
627 | |
628 private: | |
629 DISALLOW_COPY_AND_ASSIGN(GetMobileBookmarksNodeTask); | |
630 }; | |
631 | |
632 // ------------- Aynchronous requests classes ------------- // | 344 // ------------- Aynchronous requests classes ------------- // |
633 | 345 |
634 // Base class for asynchronous blocking requests to Chromium services. | 346 // Base class for asynchronous blocking requests to Chromium services. |
635 // Service: type of the service to use (e.g. HistoryService, FaviconService). | 347 // Service: type of the service to use (e.g. HistoryService, FaviconService). |
636 template <typename Service> | 348 template <typename Service> |
637 class AsyncServiceRequest : protected BlockingUIThreadAsyncRequest { | 349 class AsyncServiceRequest : protected BlockingUIThreadAsyncRequest { |
638 public: | 350 public: |
639 AsyncServiceRequest(Service* service, | 351 AsyncServiceRequest(Service* service, |
640 base::CancelableTaskTracker* cancelable_tracker) | 352 base::CancelableTaskTracker* cancelable_tracker) |
641 : service_(service), cancelable_tracker_(cancelable_tracker) {} | 353 : service_(service), cancelable_tracker_(cancelable_tracker) {} |
642 | 354 |
643 Service* service() const { return service_; } | 355 Service* service() const { return service_; } |
644 | 356 |
645 base::CancelableTaskTracker* cancelable_tracker() const { | 357 base::CancelableTaskTracker* cancelable_tracker() const { |
646 return cancelable_tracker_; | 358 return cancelable_tracker_; |
647 } | 359 } |
648 | 360 |
649 private: | 361 private: |
650 Service* service_; | 362 Service* service_; |
651 base::CancelableTaskTracker* cancelable_tracker_; | 363 base::CancelableTaskTracker* cancelable_tracker_; |
652 | 364 |
653 DISALLOW_COPY_AND_ASSIGN(AsyncServiceRequest); | 365 DISALLOW_COPY_AND_ASSIGN(AsyncServiceRequest); |
654 }; | 366 }; |
655 | 367 |
656 // Base class for all asynchronous blocking tasks that use the favicon service. | |
657 class FaviconServiceTask : public AsyncServiceRequest<favicon::FaviconService> { | |
658 public: | |
659 FaviconServiceTask(base::CancelableTaskTracker* cancelable_tracker, | |
660 Profile* profile, | |
661 favicon::FaviconService* favicon_service) | |
662 : AsyncServiceRequest<favicon::FaviconService>(favicon_service, | |
663 cancelable_tracker), | |
664 profile_(profile) {} | |
665 | |
666 Profile* profile() const { return profile_; } | |
667 | |
668 private: | |
669 Profile* profile_; | |
670 | |
671 DISALLOW_COPY_AND_ASSIGN(FaviconServiceTask); | |
672 }; | |
673 | |
674 // Retrieves the favicon or touch icon for a URL from the FaviconService. | |
675 class BookmarkIconFetchTask : public FaviconServiceTask { | |
676 public: | |
677 BookmarkIconFetchTask(base::CancelableTaskTracker* cancelable_tracker, | |
678 Profile* profile, | |
679 favicon::FaviconService* favicon_service) | |
680 : FaviconServiceTask(cancelable_tracker, profile, favicon_service) {} | |
681 | |
682 favicon_base::FaviconRawBitmapResult Run(const GURL& url) { | |
683 float max_scale = ui::GetScaleForScaleFactor( | |
684 ResourceBundle::GetSharedInstance().GetMaxScaleFactor()); | |
685 int desired_size_in_pixel = std::ceil(gfx::kFaviconSize * max_scale); | |
686 | |
687 if (service() == NULL) | |
688 return favicon_base::FaviconRawBitmapResult(); | |
689 | |
690 RunAsyncRequestOnUIThreadBlocking(base::Bind( | |
691 &favicon::FaviconService::GetRawFaviconForPageURL, | |
692 base::Unretained(service()), url, | |
693 favicon_base::FAVICON | favicon_base::TOUCH_ICON, desired_size_in_pixel, | |
694 base::Bind(&BookmarkIconFetchTask::OnFaviconRetrieved, | |
695 base::Unretained(this)), | |
696 cancelable_tracker())); | |
697 return result_; | |
698 } | |
699 | |
700 private: | |
701 void OnFaviconRetrieved( | |
702 const favicon_base::FaviconRawBitmapResult& bitmap_result) { | |
703 result_ = bitmap_result; | |
704 RequestCompleted(); | |
705 } | |
706 | |
707 favicon_base::FaviconRawBitmapResult result_; | |
708 | |
709 DISALLOW_COPY_AND_ASSIGN(BookmarkIconFetchTask); | |
710 }; | |
711 | |
712 // Base class for all asynchronous blocking tasks that use the Android history | 368 // Base class for all asynchronous blocking tasks that use the Android history |
713 // provider service. | 369 // provider service. |
714 class HistoryProviderTask | 370 class HistoryProviderTask |
715 : public AsyncServiceRequest<AndroidHistoryProviderService> { | 371 : public AsyncServiceRequest<AndroidHistoryProviderService> { |
716 public: | 372 public: |
717 HistoryProviderTask(AndroidHistoryProviderService* service, | 373 HistoryProviderTask(AndroidHistoryProviderService* service, |
718 base::CancelableTaskTracker* cancelable_tracker) | 374 base::CancelableTaskTracker* cancelable_tracker) |
719 : AsyncServiceRequest<AndroidHistoryProviderService>(service, | 375 : AsyncServiceRequest<AndroidHistoryProviderService>(service, |
720 cancelable_tracker) { | 376 cancelable_tracker) { |
721 } | 377 } |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1490 std::string where_clause; | 1146 std::string where_clause; |
1491 if (selections) | 1147 if (selections) |
1492 where_clause = ConvertJavaStringToUTF8(env, selections); | 1148 where_clause = ConvertJavaStringToUTF8(env, selections); |
1493 | 1149 |
1494 RemoveSearchTermsFromAPITask task(service_.get(), | 1150 RemoveSearchTermsFromAPITask task(service_.get(), |
1495 &cancelable_task_tracker_, | 1151 &cancelable_task_tracker_, |
1496 profile_); | 1152 profile_); |
1497 return task.Run(where_clause, where_args); | 1153 return task.Run(where_clause, where_args); |
1498 } | 1154 } |
1499 | 1155 |
1500 // ------------- Provider custom APIs ------------- // | |
1501 | |
1502 jboolean ChromeBrowserProvider::BookmarkNodeExists( | |
1503 JNIEnv* env, | |
1504 const JavaParamRef<jobject>& obj, | |
1505 jlong id) { | |
1506 BookmarkNodeExistsTask task(bookmark_model_); | |
1507 return task.Run(id); | |
1508 } | |
1509 | |
1510 jlong ChromeBrowserProvider::CreateBookmarksFolderOnce( | |
1511 JNIEnv* env, | |
1512 const JavaParamRef<jobject>& obj, | |
1513 const JavaParamRef<jstring>& jtitle, | |
1514 jlong parent_id) { | |
1515 base::string16 title = ConvertJavaStringToUTF16(env, jtitle); | |
1516 if (title.empty()) | |
1517 return kInvalidBookmarkId; | |
1518 | |
1519 CreateBookmarksFolderOnceTask task(bookmark_model_); | |
1520 return task.Run(title, parent_id); | |
1521 } | |
1522 | |
1523 ScopedJavaLocalRef<jobject> ChromeBrowserProvider::GetEditableBookmarkFolders( | |
1524 JNIEnv* env, | |
1525 const JavaParamRef<jobject>& obj) { | |
1526 ScopedJavaGlobalRef<jobject> jroot; | |
1527 ManagedBookmarkService* managed = | |
1528 ManagedBookmarkServiceFactory::GetForProfile(profile_); | |
1529 BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_); | |
1530 GetEditableBookmarkFoldersTask task(managed, model); | |
1531 task.Run(&jroot); | |
1532 return ScopedJavaLocalRef<jobject>(jroot); | |
1533 } | |
1534 | |
1535 void ChromeBrowserProvider::RemoveAllUserBookmarks( | |
1536 JNIEnv* env, | |
1537 const JavaParamRef<jobject>& obj) { | |
1538 LOG(ERROR) << "begin ChromeBrowserProvider::RemoveAllUserBookmarks"; | |
1539 RemoveAllUserBookmarksTask task(bookmark_model_); | |
1540 task.Run(); | |
1541 LOG(ERROR) << "end ChromeBrowserProvider::RemoveAllUserBookmarks"; | |
1542 } | |
1543 | |
1544 ScopedJavaLocalRef<jobject> ChromeBrowserProvider::GetBookmarkNode( | |
1545 JNIEnv* env, | |
1546 const JavaParamRef<jobject>& obj, | |
1547 jlong id, | |
1548 jboolean get_parent, | |
1549 jboolean get_children) { | |
1550 ScopedJavaGlobalRef<jobject> jnode; | |
1551 GetBookmarkNodeTask task(bookmark_model_); | |
1552 task.Run(id, get_parent, get_children, &jnode); | |
1553 return ScopedJavaLocalRef<jobject>(jnode); | |
1554 } | |
1555 | |
1556 ScopedJavaLocalRef<jobject> ChromeBrowserProvider::GetMobileBookmarksFolder( | |
1557 JNIEnv* env, | |
1558 const JavaParamRef<jobject>& obj) { | |
1559 ScopedJavaGlobalRef<jobject> jnode; | |
1560 GetMobileBookmarksNodeTask task(bookmark_model_); | |
1561 ConvertBookmarkNode(task.Run(), ScopedJavaLocalRef<jobject>(), &jnode); | |
1562 return ScopedJavaLocalRef<jobject>(jnode); | |
1563 } | |
1564 | |
1565 jboolean ChromeBrowserProvider::IsBookmarkInMobileBookmarksBranch( | |
1566 JNIEnv* env, | |
1567 const JavaParamRef<jobject>& obj, | |
1568 jlong id) { | |
1569 IsInMobileBookmarksBranchTask task(bookmark_model_); | |
1570 return task.Run(id); | |
1571 } | |
1572 | |
1573 ScopedJavaLocalRef<jbyteArray> ChromeBrowserProvider::GetFaviconOrTouchIcon( | |
1574 JNIEnv* env, | |
1575 const JavaParamRef<jobject>& obj, | |
1576 const JavaParamRef<jstring>& jurl) { | |
1577 if (!jurl) | |
1578 return ScopedJavaLocalRef<jbyteArray>(); | |
1579 | |
1580 GURL url = GURL(ConvertJavaStringToUTF16(env, jurl)); | |
1581 BookmarkIconFetchTask favicon_task(&cancelable_task_tracker_, profile_, | |
1582 favicon_service_); | |
1583 favicon_base::FaviconRawBitmapResult bitmap_result = favicon_task.Run(url); | |
1584 | |
1585 if (!bitmap_result.is_valid() || !bitmap_result.bitmap_data.get()) | |
1586 return ScopedJavaLocalRef<jbyteArray>(); | |
1587 | |
1588 return base::android::ToJavaByteArray(env, bitmap_result.bitmap_data->front(), | |
1589 bitmap_result.bitmap_data->size()); | |
1590 } | |
1591 | |
1592 ScopedJavaLocalRef<jbyteArray> ChromeBrowserProvider::GetThumbnail( | |
1593 JNIEnv* env, | |
1594 const JavaParamRef<jobject>& obj, | |
1595 const JavaParamRef<jstring>& jurl) { | |
1596 if (!jurl) | |
1597 return ScopedJavaLocalRef<jbyteArray>(); | |
1598 GURL url = GURL(ConvertJavaStringToUTF16(env, jurl)); | |
1599 | |
1600 // GetPageThumbnail is synchronous and can be called from any thread. | |
1601 scoped_refptr<base::RefCountedMemory> thumbnail; | |
1602 if (top_sites_) | |
1603 top_sites_->GetPageThumbnail(url, false, &thumbnail); | |
1604 | |
1605 if (!thumbnail.get() || !thumbnail->front()) { | |
1606 return ScopedJavaLocalRef<jbyteArray>(); | |
1607 } | |
1608 | |
1609 return base::android::ToJavaByteArray(env, thumbnail->front(), | |
1610 thumbnail->size()); | |
1611 } | |
1612 | |
1613 // ------------- Observer-related methods ------------- // | 1156 // ------------- Observer-related methods ------------- // |
1614 | 1157 |
1615 void ChromeBrowserProvider::ExtensiveBookmarkChangesBeginning( | 1158 void ChromeBrowserProvider::ExtensiveBookmarkChangesBeginning( |
1616 BookmarkModel* model) { | 1159 BookmarkModel* model) { |
1617 handling_extensive_changes_ = true; | 1160 handling_extensive_changes_ = true; |
1618 } | 1161 } |
1619 | 1162 |
1620 void ChromeBrowserProvider::ExtensiveBookmarkChangesEnded( | 1163 void ChromeBrowserProvider::ExtensiveBookmarkChangesEnded( |
1621 BookmarkModel* model) { | 1164 BookmarkModel* model) { |
1622 handling_extensive_changes_ = false; | 1165 handling_extensive_changes_ = false; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1670 ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env); | 1213 ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env); |
1671 if (obj.is_null()) | 1214 if (obj.is_null()) |
1672 return; | 1215 return; |
1673 Java_ChromeBrowserProvider_onSearchTermChanged(env, obj.obj()); | 1216 Java_ChromeBrowserProvider_onSearchTermChanged(env, obj.obj()); |
1674 } | 1217 } |
1675 | 1218 |
1676 void ChromeBrowserProvider::OnKeywordSearchTermDeleted( | 1219 void ChromeBrowserProvider::OnKeywordSearchTermDeleted( |
1677 history::HistoryService* history_service, | 1220 history::HistoryService* history_service, |
1678 history::URLID url_id) { | 1221 history::URLID url_id) { |
1679 } | 1222 } |
OLD | NEW |