Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chrome/browser/bookmarks/bookmark_model.cc

Issue 242693003: Introduce BookmarkClient interface to abstract embedder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compilation of unit tests Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698