| 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 |