| 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/bookmarks/bookmark_model.h" | 5 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/files/file_path.h" |
| 12 #include "base/i18n/string_compare.h" | 13 #include "base/i18n/string_compare.h" |
| 14 #include "base/prefs/pref_service.h" |
| 13 #include "base/sequenced_task_runner.h" | 15 #include "base/sequenced_task_runner.h" |
| 14 #include "chrome/browser/bookmarks/bookmark_expanded_state_tracker.h" | 16 #include "chrome/browser/bookmarks/bookmark_expanded_state_tracker.h" |
| 15 #include "chrome/browser/bookmarks/bookmark_index.h" | 17 #include "chrome/browser/bookmarks/bookmark_index.h" |
| 16 #include "chrome/browser/bookmarks/bookmark_model_observer.h" | 18 #include "chrome/browser/bookmarks/bookmark_model_observer.h" |
| 17 #include "chrome/browser/bookmarks/bookmark_storage.h" | 19 #include "chrome/browser/bookmarks/bookmark_storage.h" |
| 18 #include "chrome/browser/bookmarks/bookmark_utils.h" | 20 #include "chrome/browser/bookmarks/bookmark_utils.h" |
| 19 #include "chrome/browser/chrome_notification_types.h" | 21 #include "chrome/browser/chrome_notification_types.h" |
| 20 #include "chrome/browser/favicon/favicon_changed_details.h" | 22 #include "chrome/browser/favicon/favicon_changed_details.h" |
| 21 #include "chrome/browser/favicon/favicon_service.h" | 23 #include "chrome/browser/favicon/favicon_service.h" |
| 22 #include "chrome/browser/favicon/favicon_service_factory.h" | 24 #include "chrome/browser/favicon/favicon_service_factory.h" |
| 23 #include "chrome/browser/history/history_service.h" | 25 #include "chrome/browser/history/history_service.h" |
| 24 #include "chrome/browser/history/history_service_factory.h" | 26 #include "chrome/browser/history/history_service_factory.h" |
| 27 #include "chrome/browser/history/url_database.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
| 26 #include "components/bookmarks/core/browser/bookmark_title_match.h" | 29 #include "components/bookmarks/core/browser/bookmark_title_match.h" |
| 27 #include "components/favicon_base/favicon_types.h" | 30 #include "components/favicon_base/favicon_types.h" |
| 28 #include "content/public/browser/notification_details.h" | 31 #include "content/public/browser/notification_details.h" |
| 29 #include "content/public/browser/notification_source.h" | 32 #include "content/public/browser/notification_source.h" |
| 33 #include "content/public/browser/user_metrics.h" |
| 30 #include "grit/generated_resources.h" | 34 #include "grit/generated_resources.h" |
| 31 #include "ui/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
| 32 #include "ui/gfx/favicon_size.h" | 36 #include "ui/gfx/favicon_size.h" |
| 33 #include "ui/gfx/image/image_util.h" | 37 #include "ui/gfx/image/image_util.h" |
| 34 | 38 |
| 35 using base::Time; | 39 using base::Time; |
| 36 | 40 |
| 37 namespace { | 41 namespace { |
| 38 | 42 |
| 39 // Helper to get a mutable bookmark node. | 43 // Helper to get a mutable bookmark node. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 63 } | 67 } |
| 64 | 68 |
| 65 private: | 69 private: |
| 66 icu::Collator* collator_; | 70 icu::Collator* collator_; |
| 67 }; | 71 }; |
| 68 | 72 |
| 69 } // namespace | 73 } // namespace |
| 70 | 74 |
| 71 // BookmarkModel -------------------------------------------------------------- | 75 // BookmarkModel -------------------------------------------------------------- |
| 72 | 76 |
| 73 BookmarkModel::BookmarkModel(Profile* profile) | 77 BookmarkModel::BookmarkModel(BookmarkClient* client) |
| 74 : profile_(profile), | 78 : client_(client), |
| 75 loaded_(false), | 79 loaded_(false), |
| 76 root_(GURL()), | 80 root_(GURL()), |
| 77 bookmark_bar_node_(NULL), | 81 bookmark_bar_node_(NULL), |
| 78 other_node_(NULL), | 82 other_node_(NULL), |
| 79 mobile_node_(NULL), | 83 mobile_node_(NULL), |
| 80 next_node_id_(1), | 84 next_node_id_(1), |
| 81 observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), | 85 observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), |
| 82 loaded_signal_(true, false), | 86 loaded_signal_(true, false), |
| 83 extensive_changes_(0) { | 87 extensive_changes_(0) { |
| 84 if (!profile_) { | 88 if (!client_) { |
| 85 // Profile is null during testing. | 89 // client is null during testing. |
| 86 DoneLoading(CreateLoadDetails()); | 90 DoneLoading(CreateLoadDetails()); |
| 87 } | 91 } |
| 88 } | 92 } |
| 89 | 93 |
| 90 BookmarkModel::~BookmarkModel() { | 94 BookmarkModel::~BookmarkModel() { |
| 91 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 95 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 92 BookmarkModelBeingDeleted(this)); | 96 BookmarkModelBeingDeleted(this)); |
| 93 | 97 |
| 94 if (store_.get()) { | 98 if (store_.get()) { |
| 95 // The store maintains a reference back to us. We need to tell it we're gone | 99 // The store maintains a reference back to us. We need to tell it we're gone |
| 96 // so that it doesn't try and invoke a method back on us again. | 100 // so that it doesn't try and invoke a method back on us again. |
| 97 store_->BookmarkModelDeleted(); | 101 store_->BookmarkModelDeleted(); |
| 98 } | 102 } |
| 99 } | 103 } |
| 100 | 104 |
| 101 void BookmarkModel::Shutdown() { | 105 void BookmarkModel::Shutdown() { |
| 102 if (loaded_) | 106 if (loaded_) |
| 103 return; | 107 return; |
| 104 | 108 |
| 105 // See comment in HistoryService::ShutdownOnUIThread where this is invoked for | 109 // See comment in HistoryService::ShutdownOnUIThread where this is invoked for |
| 106 // details. It is also called when the BookmarkModel is deleted. | 110 // details. It is also called when the BookmarkModel is deleted. |
| 107 loaded_signal_.Signal(); | 111 loaded_signal_.Signal(); |
| 108 } | 112 } |
| 109 | 113 |
| 110 void BookmarkModel::Load( | 114 void BookmarkModel::Load( |
| 111 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { | 115 PrefService* pref_service, |
| 116 const base::FilePath& profile_path, |
| 117 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner, |
| 118 const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) { |
| 112 if (store_.get()) { | 119 if (store_.get()) { |
| 113 // If the store is non-null, it means Load was already invoked. Load should | 120 // If the store is non-null, it means Load was already invoked. Load should |
| 114 // only be invoked once. | 121 // only be invoked once. |
| 115 NOTREACHED(); | 122 NOTREACHED(); |
| 116 return; | 123 return; |
| 117 } | 124 } |
| 118 | 125 |
| 119 expanded_state_tracker_.reset( | 126 expanded_state_tracker_.reset( |
| 120 new BookmarkExpandedStateTracker(this, profile_->GetPrefs())); | 127 new BookmarkExpandedStateTracker(this, pref_service)); |
| 121 | 128 |
| 122 // Listen for changes to favicons so that we can update the favicon of the | 129 client_->OnLoad(); |
| 123 // node appropriately. | |
| 124 registrar_.Add(this, chrome::NOTIFICATION_FAVICON_CHANGED, | |
| 125 content::Source<Profile>(profile_)); | |
| 126 | 130 |
| 127 // Load the bookmarks. BookmarkStorage notifies us when done. | 131 // Load the bookmarks. BookmarkStorage notifies us when done. |
| 128 store_ = new BookmarkStorage(profile_, this, task_runner.get()); | 132 store_ = new BookmarkStorage(this, profile_path, io_task_runner.get()); |
| 129 store_->LoadBookmarks(CreateLoadDetails()); | 133 store_->LoadBookmarks(CreateLoadDetails(), ui_task_runner); |
| 130 } | 134 } |
| 131 | 135 |
| 132 const BookmarkNode* BookmarkModel::GetParentForNewNodes() { | 136 const BookmarkNode* BookmarkModel::GetParentForNewNodes() { |
| 133 std::vector<const BookmarkNode*> nodes = | 137 std::vector<const BookmarkNode*> nodes = |
| 134 bookmark_utils::GetMostRecentlyModifiedFolders(this, 1); | 138 bookmark_utils::GetMostRecentlyModifiedFolders(this, 1); |
| 135 DCHECK(!nodes.empty()); // This list is always padded with default folders. | 139 DCHECK(!nodes.empty()); // This list is always padded with default folders. |
| 136 return nodes[0]; | 140 return nodes[0]; |
| 137 } | 141 } |
| 138 | 142 |
| 139 void BookmarkModel::AddObserver(BookmarkModelObserver* observer) { | 143 void BookmarkModel::AddObserver(BookmarkModelObserver* observer) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 BookmarkNode* child_node = permanent_node->GetChild(j); | 201 BookmarkNode* child_node = permanent_node->GetChild(j); |
| 198 removed_nodes.push_back(child_node); | 202 removed_nodes.push_back(child_node); |
| 199 RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); | 203 RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); |
| 200 } | 204 } |
| 201 } | 205 } |
| 202 } | 206 } |
| 203 EndExtensiveChanges(); | 207 EndExtensiveChanges(); |
| 204 if (store_.get()) | 208 if (store_.get()) |
| 205 store_->ScheduleSave(); | 209 store_->ScheduleSave(); |
| 206 | 210 |
| 207 NotifyHistoryAboutRemovedBookmarks(removed_urls); | 211 client_->NotifyHistoryAboutRemovedBookmarks(removed_urls); |
| 208 | 212 |
| 209 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 213 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 210 BookmarkAllNodesRemoved(this)); | 214 BookmarkAllNodesRemoved(this)); |
| 211 } | 215 } |
| 212 | 216 |
| 213 void BookmarkModel::Move(const BookmarkNode* node, | 217 void BookmarkModel::Move(const BookmarkNode* node, |
| 214 const BookmarkNode* new_parent, | 218 const BookmarkNode* new_parent, |
| 215 int index) { | 219 int index) { |
| 216 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || | 220 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || |
| 217 is_root_node(new_parent) || is_permanent_node(node)) { | 221 is_root_node(new_parent) || is_permanent_node(node)) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 const BookmarkNode* node, | 410 const BookmarkNode* node, |
| 407 int64 sync_transaction_version) { | 411 int64 sync_transaction_version) { |
| 408 if (sync_transaction_version == node->sync_transaction_version()) | 412 if (sync_transaction_version == node->sync_transaction_version()) |
| 409 return; | 413 return; |
| 410 | 414 |
| 411 AsMutable(node)->set_sync_transaction_version(sync_transaction_version); | 415 AsMutable(node)->set_sync_transaction_version(sync_transaction_version); |
| 412 if (store_.get()) | 416 if (store_.get()) |
| 413 store_->ScheduleSave(); | 417 store_->ScheduleSave(); |
| 414 } | 418 } |
| 415 | 419 |
| 420 void BookmarkModel::OnFaviconChanged(const std::set<GURL>& urls) { |
| 421 // Prevent the observers from getting confused for multiple favicon loads. |
| 422 for (std::set<GURL>::const_iterator i = urls.begin(); i != urls.end(); ++i) { |
| 423 std::vector<const BookmarkNode*> nodes; |
| 424 GetNodesByURL(*i, &nodes); |
| 425 for (size_t i = 0; i < nodes.size(); ++i) { |
| 426 // Got an updated favicon, for a URL, do a new request. |
| 427 BookmarkNode* node = AsMutable(nodes[i]); |
| 428 node->InvalidateFavicon(); |
| 429 CancelPendingFaviconLoadRequests(node); |
| 430 FOR_EACH_OBSERVER(BookmarkModelObserver, |
| 431 observers_, |
| 432 BookmarkNodeFaviconChanged(this, node)); |
| 433 } |
| 434 } |
| 435 } |
| 436 |
| 416 void BookmarkModel::SetDateAdded(const BookmarkNode* node, | 437 void BookmarkModel::SetDateAdded(const BookmarkNode* node, |
| 417 base::Time date_added) { | 438 base::Time date_added) { |
| 418 if (!node) { | 439 if (!node) { |
| 419 NOTREACHED(); | 440 NOTREACHED(); |
| 420 return; | 441 return; |
| 421 } | 442 } |
| 422 | 443 |
| 423 if (node->date_added() == date_added) | 444 if (node->date_added() == date_added) |
| 424 return; | 445 return; |
| 425 | 446 |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 const base::string16& text, | 639 const base::string16& text, |
| 619 size_t max_count, | 640 size_t max_count, |
| 620 std::vector<BookmarkTitleMatch>* matches) { | 641 std::vector<BookmarkTitleMatch>* matches) { |
| 621 if (!loaded_) | 642 if (!loaded_) |
| 622 return; | 643 return; |
| 623 | 644 |
| 624 index_->GetBookmarksWithTitlesMatching(text, max_count, matches); | 645 index_->GetBookmarksWithTitlesMatching(text, max_count, matches); |
| 625 } | 646 } |
| 626 | 647 |
| 627 void BookmarkModel::ClearStore() { | 648 void BookmarkModel::ClearStore() { |
| 628 registrar_.RemoveAll(); | 649 client_->OnClearStore(); |
| 629 store_ = NULL; | 650 store_ = NULL; |
| 630 } | 651 } |
| 631 | 652 |
| 632 void BookmarkModel::SetPermanentNodeVisible(BookmarkNode::Type type, | 653 void BookmarkModel::SetPermanentNodeVisible(BookmarkNode::Type type, |
| 633 bool value) { | 654 bool value) { |
| 634 DCHECK(loaded_); | 655 DCHECK(loaded_); |
| 635 switch (type) { | 656 switch (type) { |
| 636 case BookmarkNode::BOOKMARK_BAR: | 657 case BookmarkNode::BOOKMARK_BAR: |
| 637 bookmark_bar_node_->set_visible(value); | 658 bookmark_bar_node_->set_visible(value); |
| 638 break; | 659 break; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 | 755 |
| 735 std::set<GURL> removed_urls; | 756 std::set<GURL> removed_urls; |
| 736 { | 757 { |
| 737 base::AutoLock url_lock(url_lock_); | 758 base::AutoLock url_lock(url_lock_); |
| 738 RemoveNodeAndGetRemovedUrls(node.get(), &removed_urls); | 759 RemoveNodeAndGetRemovedUrls(node.get(), &removed_urls); |
| 739 } | 760 } |
| 740 | 761 |
| 741 if (store_.get()) | 762 if (store_.get()) |
| 742 store_->ScheduleSave(); | 763 store_->ScheduleSave(); |
| 743 | 764 |
| 744 NotifyHistoryAboutRemovedBookmarks(removed_urls); | 765 client_->NotifyHistoryAboutRemovedBookmarks(removed_urls); |
| 745 | 766 |
| 746 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 767 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 747 BookmarkNodeRemoved(this, parent, index, node.get())); | 768 BookmarkNodeRemoved(this, parent, index, node.get())); |
| 748 } | 769 } |
| 749 | 770 |
| 750 void BookmarkModel::RemoveNodeFromURLSet(BookmarkNode* node) { | 771 void BookmarkModel::RemoveNodeFromURLSet(BookmarkNode* node) { |
| 751 // NOTE: this is called in such a way that url_lock_ is already held. As | 772 // NOTE: this is called in such a way that url_lock_ is already held. As |
| 752 // such, this doesn't explicitly grab the lock. | 773 // such, this doesn't explicitly grab the lock. |
| 753 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); | 774 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); |
| 754 DCHECK(i != nodes_ordered_by_url_set_.end()); | 775 DCHECK(i != nodes_ordered_by_url_set_.end()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 778 // invalidated, so using i++ here within the "erase" call is | 799 // invalidated, so using i++ here within the "erase" call is |
| 779 // important as it advances the iterator before passing the | 800 // important as it advances the iterator before passing the |
| 780 // old value through to erase. | 801 // old value through to erase. |
| 781 removed_urls->erase(i++); | 802 removed_urls->erase(i++); |
| 782 } else { | 803 } else { |
| 783 ++i; | 804 ++i; |
| 784 } | 805 } |
| 785 } | 806 } |
| 786 } | 807 } |
| 787 | 808 |
| 788 void BookmarkModel::NotifyHistoryAboutRemovedBookmarks( | |
| 789 const std::set<GURL>& removed_bookmark_urls) const { | |
| 790 if (removed_bookmark_urls.empty()) { | |
| 791 // No point in sending out notification if the starred state didn't change. | |
| 792 return; | |
| 793 } | |
| 794 | |
| 795 if (profile_) { | |
| 796 HistoryService* history = | |
| 797 HistoryServiceFactory::GetForProfile(profile_, | |
| 798 Profile::EXPLICIT_ACCESS); | |
| 799 if (history) | |
| 800 history->URLsNoLongerBookmarked(removed_bookmark_urls); | |
| 801 } | |
| 802 } | |
| 803 | |
| 804 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, | 809 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, |
| 805 int index, | 810 int index, |
| 806 BookmarkNode* node) { | 811 BookmarkNode* node) { |
| 807 parent->Add(node, index); | 812 parent->Add(node, index); |
| 808 | 813 |
| 809 if (store_.get()) | 814 if (store_.get()) |
| 810 store_->ScheduleSave(); | 815 store_->ScheduleSave(); |
| 811 | 816 |
| 812 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 817 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 813 BookmarkNodeAdded(this, parent, index)); | 818 BookmarkNodeAdded(this, parent, index)); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 node->set_icon_url(image_result.icon_url); | 885 node->set_icon_url(image_result.icon_url); |
| 881 FaviconLoaded(node); | 886 FaviconLoaded(node); |
| 882 } | 887 } |
| 883 } | 888 } |
| 884 | 889 |
| 885 void BookmarkModel::LoadFavicon(BookmarkNode* node) { | 890 void BookmarkModel::LoadFavicon(BookmarkNode* node) { |
| 886 if (node->is_folder()) | 891 if (node->is_folder()) |
| 887 return; | 892 return; |
| 888 | 893 |
| 889 DCHECK(node->url().is_valid()); | 894 DCHECK(node->url().is_valid()); |
| 890 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile( | 895 base::CancelableTaskTracker::TaskId taskId = client_->GetFaviconImageForURL( |
| 891 profile_, Profile::EXPLICIT_ACCESS); | 896 node->url(), |
| 892 if (!favicon_service) | 897 favicon_base::FAVICON, |
| 893 return; | 898 gfx::kFaviconSize, |
| 894 base::CancelableTaskTracker::TaskId taskId = | 899 base::Bind( |
| 895 favicon_service->GetFaviconImageForURL( | 900 &BookmarkModel::OnFaviconDataAvailable, base::Unretained(this), node), |
| 896 FaviconService::FaviconForURLParams( | 901 &cancelable_task_tracker_); |
| 897 node->url(), favicon_base::FAVICON, gfx::kFaviconSize), | 902 if (taskId != base::CancelableTaskTracker::kBadTaskId) |
| 898 base::Bind(&BookmarkModel::OnFaviconDataAvailable, | 903 node->set_favicon_load_task_id(taskId); |
| 899 base::Unretained(this), | |
| 900 node), | |
| 901 &cancelable_task_tracker_); | |
| 902 node->set_favicon_load_task_id(taskId); | |
| 903 } | 904 } |
| 904 | 905 |
| 905 void BookmarkModel::FaviconLoaded(const BookmarkNode* node) { | 906 void BookmarkModel::FaviconLoaded(const BookmarkNode* node) { |
| 906 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 907 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 907 BookmarkNodeFaviconChanged(this, node)); | 908 BookmarkNodeFaviconChanged(this, node)); |
| 908 } | 909 } |
| 909 | 910 |
| 910 void BookmarkModel::CancelPendingFaviconLoadRequests(BookmarkNode* node) { | 911 void BookmarkModel::CancelPendingFaviconLoadRequests(BookmarkNode* node) { |
| 911 if (node->favicon_load_task_id() != base::CancelableTaskTracker::kBadTaskId) { | 912 if (node->favicon_load_task_id() != base::CancelableTaskTracker::kBadTaskId) { |
| 912 cancelable_task_tracker_.TryCancel(node->favicon_load_task_id()); | 913 cancelable_task_tracker_.TryCancel(node->favicon_load_task_id()); |
| 913 node->set_favicon_load_task_id(base::CancelableTaskTracker::kBadTaskId); | 914 node->set_favicon_load_task_id(base::CancelableTaskTracker::kBadTaskId); |
| 914 } | 915 } |
| 915 } | 916 } |
| 916 | 917 |
| 917 void BookmarkModel::Observe(int type, | |
| 918 const content::NotificationSource& source, | |
| 919 const content::NotificationDetails& details) { | |
| 920 switch (type) { | |
| 921 case chrome::NOTIFICATION_FAVICON_CHANGED: { | |
| 922 // Prevent the observers from getting confused for multiple favicon loads. | |
| 923 content::Details<FaviconChangedDetails> favicon_details(details); | |
| 924 for (std::set<GURL>::const_iterator i = favicon_details->urls.begin(); | |
| 925 i != favicon_details->urls.end(); ++i) { | |
| 926 std::vector<const BookmarkNode*> nodes; | |
| 927 GetNodesByURL(*i, &nodes); | |
| 928 for (size_t i = 0; i < nodes.size(); ++i) { | |
| 929 // Got an updated favicon, for a URL, do a new request. | |
| 930 BookmarkNode* node = AsMutable(nodes[i]); | |
| 931 node->InvalidateFavicon(); | |
| 932 CancelPendingFaviconLoadRequests(node); | |
| 933 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | |
| 934 BookmarkNodeFaviconChanged(this, node)); | |
| 935 } | |
| 936 } | |
| 937 break; | |
| 938 } | |
| 939 | |
| 940 default: | |
| 941 NOTREACHED(); | |
| 942 break; | |
| 943 } | |
| 944 } | |
| 945 | |
| 946 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { | 918 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { |
| 947 // NOTE: this is called with url_lock_ already held. As such, this doesn't | 919 // NOTE: this is called with url_lock_ already held. As such, this doesn't |
| 948 // explicitly grab the lock. | 920 // explicitly grab the lock. |
| 949 if (node->is_url()) | 921 if (node->is_url()) |
| 950 nodes_ordered_by_url_set_.insert(node); | 922 nodes_ordered_by_url_set_.insert(node); |
| 951 for (int i = 0; i < node->child_count(); ++i) | 923 for (int i = 0; i < node->child_count(); ++i) |
| 952 PopulateNodesByURL(node->GetChild(i)); | 924 PopulateNodesByURL(node->GetChild(i)); |
| 953 } | 925 } |
| 954 | 926 |
| 955 int64 BookmarkModel::generate_next_node_id() { | 927 int64 BookmarkModel::generate_next_node_id() { |
| 956 return next_node_id_++; | 928 return next_node_id_++; |
| 957 } | 929 } |
| 958 | 930 |
| 959 BookmarkLoadDetails* BookmarkModel::CreateLoadDetails() { | 931 BookmarkLoadDetails* BookmarkModel::CreateLoadDetails() { |
| 960 BookmarkPermanentNode* bb_node = | 932 BookmarkPermanentNode* bb_node = |
| 961 CreatePermanentNode(BookmarkNode::BOOKMARK_BAR); | 933 CreatePermanentNode(BookmarkNode::BOOKMARK_BAR); |
| 962 BookmarkPermanentNode* other_node = | 934 BookmarkPermanentNode* other_node = |
| 963 CreatePermanentNode(BookmarkNode::OTHER_NODE); | 935 CreatePermanentNode(BookmarkNode::OTHER_NODE); |
| 964 BookmarkPermanentNode* mobile_node = | 936 BookmarkPermanentNode* mobile_node = |
| 965 CreatePermanentNode(BookmarkNode::MOBILE); | 937 CreatePermanentNode(BookmarkNode::MOBILE); |
| 966 return new BookmarkLoadDetails(bb_node, other_node, mobile_node, | 938 return new BookmarkLoadDetails(bb_node, |
| 967 new BookmarkIndex(profile_), | 939 other_node, |
| 940 mobile_node, |
| 941 new BookmarkIndex(client_), |
| 968 next_node_id_); | 942 next_node_id_); |
| 969 } | 943 } |
| 944 |
| 945 ChromeBookmarkClient::ChromeBookmarkClient(Profile* profile) |
| 946 : profile_(profile), model_(new BookmarkModel(this)) { |
| 947 } |
| 948 |
| 949 ChromeBookmarkClient::~ChromeBookmarkClient() { |
| 950 } |
| 951 |
| 952 void ChromeBookmarkClient::Shutdown() { |
| 953 model_->Shutdown(); |
| 954 } |
| 955 |
| 956 void ChromeBookmarkClient::Observe( |
| 957 int type, |
| 958 const content::NotificationSource& source, |
| 959 const content::NotificationDetails& details) { |
| 960 switch (type) { |
| 961 case chrome::NOTIFICATION_FAVICON_CHANGED: { |
| 962 content::Details<FaviconChangedDetails> favicon_details(details); |
| 963 model_->OnFaviconChanged(favicon_details->urls); |
| 964 break; |
| 965 } |
| 966 |
| 967 default: |
| 968 NOTREACHED(); |
| 969 break; |
| 970 } |
| 971 } |
| 972 |
| 973 void ChromeBookmarkClient::OnLoad() { |
| 974 // Listen for changes to favicons so that we can update the favicon of the |
| 975 // node appropriately. |
| 976 registrar_.Add(this, |
| 977 chrome::NOTIFICATION_FAVICON_CHANGED, |
| 978 content::Source<Profile>(profile_)); |
| 979 } |
| 980 |
| 981 void ChromeBookmarkClient::OnClearStore() { |
| 982 registrar_.RemoveAll(); |
| 983 } |
| 984 |
| 985 void ChromeBookmarkClient::NotifyHistoryAboutRemovedBookmarks( |
| 986 const std::set<GURL>& removed_bookmark_urls) const { |
| 987 if (removed_bookmark_urls.empty()) { |
| 988 // No point in sending out notification if the starred state didn't change. |
| 989 return; |
| 990 } |
| 991 |
| 992 HistoryService* history_service = |
| 993 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); |
| 994 if (history_service) |
| 995 history_service->URLsNoLongerBookmarked(removed_bookmark_urls); |
| 996 } |
| 997 |
| 998 base::CancelableTaskTracker::TaskId ChromeBookmarkClient::GetFaviconImageForURL( |
| 999 const GURL& page_url, |
| 1000 int icon_types, |
| 1001 int desired_size_in_dip, |
| 1002 const FaviconImageCallback& callback, |
| 1003 base::CancelableTaskTracker* tracker) { |
| 1004 FaviconService* favicon_service = |
| 1005 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); |
| 1006 if (!favicon_service) |
| 1007 return base::CancelableTaskTracker::kBadTaskId; |
| 1008 return favicon_service->GetFaviconImageForURL( |
| 1009 FaviconService::FaviconForURLParams( |
| 1010 page_url, icon_types, desired_size_in_dip), |
| 1011 callback, |
| 1012 tracker); |
| 1013 } |
| 1014 |
| 1015 bool ChromeBookmarkClient::SupportsTypedCountForNodes() { |
| 1016 return true; |
| 1017 } |
| 1018 |
| 1019 void ChromeBookmarkClient::GetTypedCountForNodes( |
| 1020 const NodeSet& nodes, |
| 1021 NodeTypedCountPairs* node_typed_count_pairs) { |
| 1022 HistoryService* history_service = |
| 1023 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); |
| 1024 history::URLDatabase* url_db = |
| 1025 history_service ? history_service->InMemoryDatabase() : NULL; |
| 1026 for (NodeSet::const_iterator i = nodes.begin(); i != nodes.end(); ++i) { |
| 1027 int typed_count = 0; |
| 1028 |
| 1029 // If |url_db| is the InMemoryDatabase, it might not cache all URLRows, but |
| 1030 // it guarantees to contain those with |typed_count| > 0. Thus, if we cannot |
| 1031 // fetch the URLRow, it is safe to assume that its |typed_count| is 0. |
| 1032 history::URLRow url; |
| 1033 if (url_db && url_db->GetRowForURL((*i)->url(), &url)) |
| 1034 typed_count = url.typed_count(); |
| 1035 |
| 1036 NodeTypedCountPair pair(*i, typed_count); |
| 1037 node_typed_count_pairs->push_back(pair); |
| 1038 } |
| 1039 } |
| 1040 |
| 1041 void ChromeBookmarkClient::RecordAction(const base::UserMetricsAction& action) { |
| 1042 content::RecordAction(action); |
| 1043 } |
| OLD | NEW |