| 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" | |
| 11 #include "base/bind_helpers.h" | |
| 12 #include "base/i18n/string_compare.h" | 10 #include "base/i18n/string_compare.h" |
| 13 #include "base/sequenced_task_runner.h" | 11 #include "base/strings/string_util.h" |
| 14 #include "chrome/browser/bookmarks/bookmark_expanded_state_tracker.h" | 12 #include "chrome/browser/bookmarks/bookmark_expanded_state_tracker.h" |
| 15 #include "chrome/browser/bookmarks/bookmark_index.h" | 13 #include "chrome/browser/bookmarks/bookmark_index.h" |
| 16 #include "chrome/browser/bookmarks/bookmark_model_observer.h" | 14 #include "chrome/browser/bookmarks/bookmark_model_observer.h" |
| 15 #include "chrome/browser/bookmarks/bookmark_node_data.h" |
| 17 #include "chrome/browser/bookmarks/bookmark_storage.h" | 16 #include "chrome/browser/bookmarks/bookmark_storage.h" |
| 18 #include "chrome/browser/bookmarks/bookmark_utils.h" | 17 #include "chrome/browser/bookmarks/bookmark_utils.h" |
| 19 #include "chrome/browser/chrome_notification_types.h" | |
| 20 #include "chrome/browser/favicon/favicon_changed_details.h" | |
| 21 #include "chrome/browser/favicon/favicon_service.h" | |
| 22 #include "chrome/browser/favicon/favicon_service_factory.h" | |
| 23 #include "chrome/browser/history/history_service.h" | |
| 24 #include "chrome/browser/history/history_service_factory.h" | |
| 25 #include "chrome/browser/profiles/profile.h" | |
| 26 #include "components/bookmarks/core/browser/bookmark_title_match.h" | |
| 27 #include "components/favicon_base/favicon_types.h" | 18 #include "components/favicon_base/favicon_types.h" |
| 28 #include "content/public/browser/notification_details.h" | |
| 29 #include "content/public/browser/notification_source.h" | |
| 30 #include "grit/component_strings.h" | 19 #include "grit/component_strings.h" |
| 31 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" |
| 32 #include "ui/gfx/favicon_size.h" | 21 #include "ui/gfx/favicon_size.h" |
| 33 #include "ui/gfx/image/image_util.h" | |
| 34 | 22 |
| 35 using base::Time; | 23 using base::Time; |
| 36 | 24 |
| 37 namespace { | 25 namespace { |
| 38 | 26 |
| 39 // Helper to get a mutable bookmark node. | 27 // Helper to get a mutable bookmark node. |
| 40 BookmarkNode* AsMutable(const BookmarkNode* node) { | 28 BookmarkNode* AsMutable(const BookmarkNode* node) { |
| 41 return const_cast<BookmarkNode*>(node); | 29 return const_cast<BookmarkNode*>(node); |
| 42 } | 30 } |
| 43 | 31 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 63 } | 51 } |
| 64 | 52 |
| 65 private: | 53 private: |
| 66 icu::Collator* collator_; | 54 icu::Collator* collator_; |
| 67 }; | 55 }; |
| 68 | 56 |
| 69 } // namespace | 57 } // namespace |
| 70 | 58 |
| 71 // BookmarkModel -------------------------------------------------------------- | 59 // BookmarkModel -------------------------------------------------------------- |
| 72 | 60 |
| 73 BookmarkModel::BookmarkModel(Profile* profile) | 61 BookmarkModel::BookmarkModel(BookmarkClient* client) |
| 74 : profile_(profile), | 62 : client_(client), |
| 75 loaded_(false), | 63 loaded_(false), |
| 76 root_(GURL()), | 64 root_(GURL()), |
| 77 bookmark_bar_node_(NULL), | 65 bookmark_bar_node_(NULL), |
| 78 other_node_(NULL), | 66 other_node_(NULL), |
| 79 mobile_node_(NULL), | 67 mobile_node_(NULL), |
| 80 next_node_id_(1), | 68 next_node_id_(1), |
| 81 observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), | 69 observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), |
| 82 loaded_signal_(true, false), | 70 loaded_signal_(true, false), |
| 83 extensive_changes_(0) { | 71 extensive_changes_(0) { |
| 84 if (!profile_) { | 72 DCHECK(client); |
| 85 // Profile is null during testing. | |
| 86 DoneLoading(CreateLoadDetails()); | |
| 87 } | |
| 88 } | 73 } |
| 89 | 74 |
| 90 BookmarkModel::~BookmarkModel() { | 75 BookmarkModel::~BookmarkModel() { |
| 91 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 76 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 92 BookmarkModelBeingDeleted(this)); | 77 BookmarkModelBeingDeleted(this)); |
| 93 | 78 |
| 94 if (store_.get()) { | 79 if (store_.get()) { |
| 95 // The store maintains a reference back to us. We need to tell it we're gone | 80 // 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. | 81 // so that it doesn't try and invoke a method back on us again. |
| 97 store_->BookmarkModelDeleted(); | 82 store_->BookmarkModelDeleted(); |
| 98 } | 83 } |
| 99 } | 84 } |
| 100 | 85 |
| 101 void BookmarkModel::Shutdown() { | 86 void BookmarkModel::Shutdown() { |
| 102 if (loaded_) | 87 if (loaded_) |
| 103 return; | 88 return; |
| 104 | 89 |
| 105 // See comment in HistoryService::ShutdownOnUIThread where this is invoked for | 90 // See comment in HistoryService::ShutdownOnUIThread where this is invoked for |
| 106 // details. It is also called when the BookmarkModel is deleted. | 91 // details. It is also called when the BookmarkModel is deleted. |
| 107 loaded_signal_.Signal(); | 92 loaded_signal_.Signal(); |
| 108 } | 93 } |
| 109 | 94 |
| 110 void BookmarkModel::Load( | 95 void BookmarkModel::Load( |
| 111 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { | 96 PrefService* pref_service, |
| 97 const base::FilePath& profile_path, |
| 98 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner, |
| 99 const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) { |
| 112 if (store_.get()) { | 100 if (store_.get()) { |
| 113 // If the store is non-null, it means Load was already invoked. Load should | 101 // If the store is non-null, it means Load was already invoked. Load should |
| 114 // only be invoked once. | 102 // only be invoked once. |
| 115 NOTREACHED(); | 103 NOTREACHED(); |
| 116 return; | 104 return; |
| 117 } | 105 } |
| 118 | 106 |
| 119 expanded_state_tracker_.reset( | 107 expanded_state_tracker_.reset( |
| 120 new BookmarkExpandedStateTracker(this, profile_->GetPrefs())); | 108 new BookmarkExpandedStateTracker(this, pref_service)); |
| 121 | 109 |
| 122 // Listen for changes to favicons so that we can update the favicon of the | 110 client_->OnLoad(); |
| 123 // node appropriately. | |
| 124 registrar_.Add(this, chrome::NOTIFICATION_FAVICON_CHANGED, | |
| 125 content::Source<Profile>(profile_)); | |
| 126 | 111 |
| 127 // Load the bookmarks. BookmarkStorage notifies us when done. | 112 // Load the bookmarks. BookmarkStorage notifies us when done. |
| 128 store_ = new BookmarkStorage(profile_, this, task_runner.get()); | 113 store_ = new BookmarkStorage(this, profile_path, io_task_runner.get()); |
| 129 store_->LoadBookmarks(CreateLoadDetails()); | 114 store_->LoadBookmarks(CreateLoadDetails(), ui_task_runner); |
| 130 } | 115 } |
| 131 | 116 |
| 132 const BookmarkNode* BookmarkModel::GetParentForNewNodes() { | 117 const BookmarkNode* BookmarkModel::GetParentForNewNodes() { |
| 133 std::vector<const BookmarkNode*> nodes = | 118 std::vector<const BookmarkNode*> nodes = |
| 134 bookmark_utils::GetMostRecentlyModifiedFolders(this, 1); | 119 bookmark_utils::GetMostRecentlyModifiedFolders(this, 1); |
| 135 DCHECK(!nodes.empty()); // This list is always padded with default folders. | 120 DCHECK(!nodes.empty()); // This list is always padded with default folders. |
| 136 return nodes[0]; | 121 return nodes[0]; |
| 137 } | 122 } |
| 138 | 123 |
| 139 void BookmarkModel::AddObserver(BookmarkModelObserver* observer) { | 124 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); | 182 BookmarkNode* child_node = permanent_node->GetChild(j); |
| 198 removed_nodes.push_back(child_node); | 183 removed_nodes.push_back(child_node); |
| 199 RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); | 184 RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); |
| 200 } | 185 } |
| 201 } | 186 } |
| 202 } | 187 } |
| 203 EndExtensiveChanges(); | 188 EndExtensiveChanges(); |
| 204 if (store_.get()) | 189 if (store_.get()) |
| 205 store_->ScheduleSave(); | 190 store_->ScheduleSave(); |
| 206 | 191 |
| 207 NotifyHistoryAboutRemovedBookmarks(removed_urls); | 192 client_->NotifyHistoryAboutRemovedBookmarks(removed_urls); |
| 208 | 193 |
| 209 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 194 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 210 BookmarkAllNodesRemoved(this)); | 195 BookmarkAllNodesRemoved(this)); |
| 211 } | 196 } |
| 212 | 197 |
| 213 void BookmarkModel::Move(const BookmarkNode* node, | 198 void BookmarkModel::Move(const BookmarkNode* node, |
| 214 const BookmarkNode* new_parent, | 199 const BookmarkNode* new_parent, |
| 215 int index) { | 200 int index) { |
| 216 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || | 201 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || |
| 217 is_root_node(new_parent) || is_permanent_node(node)) { | 202 is_root_node(new_parent) || is_permanent_node(node)) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 const gfx::Image& BookmarkModel::GetFavicon(const BookmarkNode* node) { | 263 const gfx::Image& BookmarkModel::GetFavicon(const BookmarkNode* node) { |
| 279 DCHECK(node); | 264 DCHECK(node); |
| 280 if (node->favicon_state() == BookmarkNode::INVALID_FAVICON) { | 265 if (node->favicon_state() == BookmarkNode::INVALID_FAVICON) { |
| 281 BookmarkNode* mutable_node = AsMutable(node); | 266 BookmarkNode* mutable_node = AsMutable(node); |
| 282 mutable_node->set_favicon_state(BookmarkNode::LOADING_FAVICON); | 267 mutable_node->set_favicon_state(BookmarkNode::LOADING_FAVICON); |
| 283 LoadFavicon(mutable_node); | 268 LoadFavicon(mutable_node); |
| 284 } | 269 } |
| 285 return node->favicon(); | 270 return node->favicon(); |
| 286 } | 271 } |
| 287 | 272 |
| 288 void BookmarkModel::SetTitle(const BookmarkNode* node, const base::string16& tit
le) { | 273 void BookmarkModel::SetTitle(const BookmarkNode* node, |
| 274 const base::string16& title) { |
| 289 if (!node) { | 275 if (!node) { |
| 290 NOTREACHED(); | 276 NOTREACHED(); |
| 291 return; | 277 return; |
| 292 } | 278 } |
| 293 if (node->GetTitle() == title) | 279 if (node->GetTitle() == title) |
| 294 return; | 280 return; |
| 295 | 281 |
| 296 if (is_permanent_node(node)) { | 282 if (is_permanent_node(node)) { |
| 297 NOTREACHED(); | 283 NOTREACHED(); |
| 298 return; | 284 return; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 const BookmarkNode* node, | 392 const BookmarkNode* node, |
| 407 int64 sync_transaction_version) { | 393 int64 sync_transaction_version) { |
| 408 if (sync_transaction_version == node->sync_transaction_version()) | 394 if (sync_transaction_version == node->sync_transaction_version()) |
| 409 return; | 395 return; |
| 410 | 396 |
| 411 AsMutable(node)->set_sync_transaction_version(sync_transaction_version); | 397 AsMutable(node)->set_sync_transaction_version(sync_transaction_version); |
| 412 if (store_.get()) | 398 if (store_.get()) |
| 413 store_->ScheduleSave(); | 399 store_->ScheduleSave(); |
| 414 } | 400 } |
| 415 | 401 |
| 402 void BookmarkModel::OnFaviconChanged(const std::set<GURL>& urls) { |
| 403 // Prevent the observers from getting confused for multiple favicon loads. |
| 404 for (std::set<GURL>::const_iterator i = urls.begin(); i != urls.end(); ++i) { |
| 405 std::vector<const BookmarkNode*> nodes; |
| 406 GetNodesByURL(*i, &nodes); |
| 407 for (size_t i = 0; i < nodes.size(); ++i) { |
| 408 // Got an updated favicon, for a URL, do a new request. |
| 409 BookmarkNode* node = AsMutable(nodes[i]); |
| 410 node->InvalidateFavicon(); |
| 411 CancelPendingFaviconLoadRequests(node); |
| 412 FOR_EACH_OBSERVER(BookmarkModelObserver, |
| 413 observers_, |
| 414 BookmarkNodeFaviconChanged(this, node)); |
| 415 } |
| 416 } |
| 417 } |
| 418 |
| 416 void BookmarkModel::SetDateAdded(const BookmarkNode* node, | 419 void BookmarkModel::SetDateAdded(const BookmarkNode* node, |
| 417 base::Time date_added) { | 420 base::Time date_added) { |
| 418 if (!node) { | 421 if (!node) { |
| 419 NOTREACHED(); | 422 NOTREACHED(); |
| 420 return; | 423 return; |
| 421 } | 424 } |
| 422 | 425 |
| 423 if (node->date_added() == date_added) | 426 if (node->date_added() == date_added) |
| 424 return; | 427 return; |
| 425 | 428 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 const base::string16& text, | 616 const base::string16& text, |
| 614 size_t max_count, | 617 size_t max_count, |
| 615 std::vector<BookmarkTitleMatch>* matches) { | 618 std::vector<BookmarkTitleMatch>* matches) { |
| 616 if (!loaded_) | 619 if (!loaded_) |
| 617 return; | 620 return; |
| 618 | 621 |
| 619 index_->GetBookmarksWithTitlesMatching(text, max_count, matches); | 622 index_->GetBookmarksWithTitlesMatching(text, max_count, matches); |
| 620 } | 623 } |
| 621 | 624 |
| 622 void BookmarkModel::ClearStore() { | 625 void BookmarkModel::ClearStore() { |
| 623 registrar_.RemoveAll(); | 626 client_->OnClearStore(); |
| 624 store_ = NULL; | 627 store_ = NULL; |
| 625 } | 628 } |
| 626 | 629 |
| 627 void BookmarkModel::SetPermanentNodeVisible(BookmarkNode::Type type, | 630 void BookmarkModel::SetPermanentNodeVisible(BookmarkNode::Type type, |
| 628 bool value) { | 631 bool value) { |
| 629 DCHECK(loaded_); | 632 DCHECK(loaded_); |
| 630 switch (type) { | 633 switch (type) { |
| 631 case BookmarkNode::BOOKMARK_BAR: | 634 case BookmarkNode::BOOKMARK_BAR: |
| 632 bookmark_bar_node_->set_visible(value); | 635 bookmark_bar_node_->set_visible(value); |
| 633 break; | 636 break; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 | 732 |
| 730 std::set<GURL> removed_urls; | 733 std::set<GURL> removed_urls; |
| 731 { | 734 { |
| 732 base::AutoLock url_lock(url_lock_); | 735 base::AutoLock url_lock(url_lock_); |
| 733 RemoveNodeAndGetRemovedUrls(node.get(), &removed_urls); | 736 RemoveNodeAndGetRemovedUrls(node.get(), &removed_urls); |
| 734 } | 737 } |
| 735 | 738 |
| 736 if (store_.get()) | 739 if (store_.get()) |
| 737 store_->ScheduleSave(); | 740 store_->ScheduleSave(); |
| 738 | 741 |
| 739 NotifyHistoryAboutRemovedBookmarks(removed_urls); | 742 client_->NotifyHistoryAboutRemovedBookmarks(removed_urls); |
| 740 | 743 |
| 741 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 744 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 742 BookmarkNodeRemoved(this, parent, index, node.get())); | 745 BookmarkNodeRemoved(this, parent, index, node.get())); |
| 743 } | 746 } |
| 744 | 747 |
| 745 void BookmarkModel::RemoveNodeFromURLSet(BookmarkNode* node) { | 748 void BookmarkModel::RemoveNodeFromURLSet(BookmarkNode* node) { |
| 746 // NOTE: this is called in such a way that url_lock_ is already held. As | 749 // NOTE: this is called in such a way that url_lock_ is already held. As |
| 747 // such, this doesn't explicitly grab the lock. | 750 // such, this doesn't explicitly grab the lock. |
| 748 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); | 751 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); |
| 749 DCHECK(i != nodes_ordered_by_url_set_.end()); | 752 DCHECK(i != nodes_ordered_by_url_set_.end()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 773 // invalidated, so using i++ here within the "erase" call is | 776 // invalidated, so using i++ here within the "erase" call is |
| 774 // important as it advances the iterator before passing the | 777 // important as it advances the iterator before passing the |
| 775 // old value through to erase. | 778 // old value through to erase. |
| 776 removed_urls->erase(i++); | 779 removed_urls->erase(i++); |
| 777 } else { | 780 } else { |
| 778 ++i; | 781 ++i; |
| 779 } | 782 } |
| 780 } | 783 } |
| 781 } | 784 } |
| 782 | 785 |
| 783 void BookmarkModel::NotifyHistoryAboutRemovedBookmarks( | |
| 784 const std::set<GURL>& removed_bookmark_urls) const { | |
| 785 if (removed_bookmark_urls.empty()) { | |
| 786 // No point in sending out notification if the starred state didn't change. | |
| 787 return; | |
| 788 } | |
| 789 | |
| 790 if (profile_) { | |
| 791 HistoryService* history = | |
| 792 HistoryServiceFactory::GetForProfile(profile_, | |
| 793 Profile::EXPLICIT_ACCESS); | |
| 794 if (history) | |
| 795 history->URLsNoLongerBookmarked(removed_bookmark_urls); | |
| 796 } | |
| 797 } | |
| 798 | |
| 799 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, | 786 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, |
| 800 int index, | 787 int index, |
| 801 BookmarkNode* node) { | 788 BookmarkNode* node) { |
| 802 parent->Add(node, index); | 789 parent->Add(node, index); |
| 803 | 790 |
| 804 if (store_.get()) | 791 if (store_.get()) |
| 805 store_->ScheduleSave(); | 792 store_->ScheduleSave(); |
| 806 | 793 |
| 807 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 794 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 808 BookmarkNodeAdded(this, parent, index)); | 795 BookmarkNodeAdded(this, parent, index)); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 node->set_icon_url(image_result.icon_url); | 849 node->set_icon_url(image_result.icon_url); |
| 863 FaviconLoaded(node); | 850 FaviconLoaded(node); |
| 864 } | 851 } |
| 865 } | 852 } |
| 866 | 853 |
| 867 void BookmarkModel::LoadFavicon(BookmarkNode* node) { | 854 void BookmarkModel::LoadFavicon(BookmarkNode* node) { |
| 868 if (node->is_folder()) | 855 if (node->is_folder()) |
| 869 return; | 856 return; |
| 870 | 857 |
| 871 DCHECK(node->url().is_valid()); | 858 DCHECK(node->url().is_valid()); |
| 872 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile( | 859 base::CancelableTaskTracker::TaskId taskId = client_->GetFaviconImageForURL( |
| 873 profile_, Profile::EXPLICIT_ACCESS); | 860 node->url(), |
| 874 if (!favicon_service) | 861 favicon_base::FAVICON, |
| 875 return; | 862 gfx::kFaviconSize, |
| 876 base::CancelableTaskTracker::TaskId taskId = | 863 base::Bind( |
| 877 favicon_service->GetFaviconImageForURL( | 864 &BookmarkModel::OnFaviconDataAvailable, base::Unretained(this), node), |
| 878 FaviconService::FaviconForURLParams( | 865 &cancelable_task_tracker_); |
| 879 node->url(), favicon_base::FAVICON, gfx::kFaviconSize), | 866 if (taskId != base::CancelableTaskTracker::kBadTaskId) |
| 880 base::Bind(&BookmarkModel::OnFaviconDataAvailable, | 867 node->set_favicon_load_task_id(taskId); |
| 881 base::Unretained(this), | |
| 882 node), | |
| 883 &cancelable_task_tracker_); | |
| 884 node->set_favicon_load_task_id(taskId); | |
| 885 } | 868 } |
| 886 | 869 |
| 887 void BookmarkModel::FaviconLoaded(const BookmarkNode* node) { | 870 void BookmarkModel::FaviconLoaded(const BookmarkNode* node) { |
| 888 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 871 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 889 BookmarkNodeFaviconChanged(this, node)); | 872 BookmarkNodeFaviconChanged(this, node)); |
| 890 } | 873 } |
| 891 | 874 |
| 892 void BookmarkModel::CancelPendingFaviconLoadRequests(BookmarkNode* node) { | 875 void BookmarkModel::CancelPendingFaviconLoadRequests(BookmarkNode* node) { |
| 893 if (node->favicon_load_task_id() != base::CancelableTaskTracker::kBadTaskId) { | 876 if (node->favicon_load_task_id() != base::CancelableTaskTracker::kBadTaskId) { |
| 894 cancelable_task_tracker_.TryCancel(node->favicon_load_task_id()); | 877 cancelable_task_tracker_.TryCancel(node->favicon_load_task_id()); |
| 895 node->set_favicon_load_task_id(base::CancelableTaskTracker::kBadTaskId); | 878 node->set_favicon_load_task_id(base::CancelableTaskTracker::kBadTaskId); |
| 896 } | 879 } |
| 897 } | 880 } |
| 898 | 881 |
| 899 void BookmarkModel::Observe(int type, | |
| 900 const content::NotificationSource& source, | |
| 901 const content::NotificationDetails& details) { | |
| 902 switch (type) { | |
| 903 case chrome::NOTIFICATION_FAVICON_CHANGED: { | |
| 904 // Prevent the observers from getting confused for multiple favicon loads. | |
| 905 content::Details<FaviconChangedDetails> favicon_details(details); | |
| 906 for (std::set<GURL>::const_iterator i = favicon_details->urls.begin(); | |
| 907 i != favicon_details->urls.end(); ++i) { | |
| 908 std::vector<const BookmarkNode*> nodes; | |
| 909 GetNodesByURL(*i, &nodes); | |
| 910 for (size_t i = 0; i < nodes.size(); ++i) { | |
| 911 // Got an updated favicon, for a URL, do a new request. | |
| 912 BookmarkNode* node = AsMutable(nodes[i]); | |
| 913 node->InvalidateFavicon(); | |
| 914 CancelPendingFaviconLoadRequests(node); | |
| 915 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | |
| 916 BookmarkNodeFaviconChanged(this, node)); | |
| 917 } | |
| 918 } | |
| 919 break; | |
| 920 } | |
| 921 | |
| 922 default: | |
| 923 NOTREACHED(); | |
| 924 break; | |
| 925 } | |
| 926 } | |
| 927 | |
| 928 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { | 882 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { |
| 929 // NOTE: this is called with url_lock_ already held. As such, this doesn't | 883 // NOTE: this is called with url_lock_ already held. As such, this doesn't |
| 930 // explicitly grab the lock. | 884 // explicitly grab the lock. |
| 931 if (node->is_url()) | 885 if (node->is_url()) |
| 932 nodes_ordered_by_url_set_.insert(node); | 886 nodes_ordered_by_url_set_.insert(node); |
| 933 for (int i = 0; i < node->child_count(); ++i) | 887 for (int i = 0; i < node->child_count(); ++i) |
| 934 PopulateNodesByURL(node->GetChild(i)); | 888 PopulateNodesByURL(node->GetChild(i)); |
| 935 } | 889 } |
| 936 | 890 |
| 937 int64 BookmarkModel::generate_next_node_id() { | 891 int64 BookmarkModel::generate_next_node_id() { |
| 938 return next_node_id_++; | 892 return next_node_id_++; |
| 939 } | 893 } |
| 940 | 894 |
| 941 BookmarkLoadDetails* BookmarkModel::CreateLoadDetails() { | 895 BookmarkLoadDetails* BookmarkModel::CreateLoadDetails() { |
| 942 BookmarkPermanentNode* bb_node = | 896 BookmarkPermanentNode* bb_node = |
| 943 CreatePermanentNode(BookmarkNode::BOOKMARK_BAR); | 897 CreatePermanentNode(BookmarkNode::BOOKMARK_BAR); |
| 944 BookmarkPermanentNode* other_node = | 898 BookmarkPermanentNode* other_node = |
| 945 CreatePermanentNode(BookmarkNode::OTHER_NODE); | 899 CreatePermanentNode(BookmarkNode::OTHER_NODE); |
| 946 BookmarkPermanentNode* mobile_node = | 900 BookmarkPermanentNode* mobile_node = |
| 947 CreatePermanentNode(BookmarkNode::MOBILE); | 901 CreatePermanentNode(BookmarkNode::MOBILE); |
| 948 return new BookmarkLoadDetails(bb_node, other_node, mobile_node, | 902 return new BookmarkLoadDetails(bb_node, |
| 949 new BookmarkIndex(profile_), | 903 other_node, |
| 904 mobile_node, |
| 905 new BookmarkIndex(client_), |
| 950 next_node_id_); | 906 next_node_id_); |
| 951 } | 907 } |
| OLD | NEW |