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 // The history system runs on a background thread so that potentially slow | 5 // The history system runs on a background thread so that potentially slow |
6 // database operations don't delay the browser. This backend processing is | 6 // database operations don't delay the browser. This backend processing is |
7 // represented by HistoryBackend. The HistoryService's job is to dispatch to | 7 // represented by HistoryBackend. The HistoryService's job is to dispatch to |
8 // that thread. | 8 // that thread. |
9 // | 9 // |
10 // Main thread History thread | 10 // Main thread History thread |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "base/command_line.h" | 23 #include "base/command_line.h" |
24 #include "base/compiler_specific.h" | 24 #include "base/compiler_specific.h" |
25 #include "base/location.h" | 25 #include "base/location.h" |
26 #include "base/memory/ref_counted.h" | 26 #include "base/memory/ref_counted.h" |
27 #include "base/message_loop/message_loop.h" | 27 #include "base/message_loop/message_loop.h" |
28 #include "base/prefs/pref_service.h" | 28 #include "base/prefs/pref_service.h" |
29 #include "base/thread_task_runner_handle.h" | 29 #include "base/thread_task_runner_handle.h" |
30 #include "base/threading/thread.h" | 30 #include "base/threading/thread.h" |
31 #include "base/time/time.h" | 31 #include "base/time/time.h" |
32 #include "chrome/browser/browser_process.h" | 32 #include "chrome/browser/browser_process.h" |
33 #include "chrome/browser/chrome_notification_types.h" | |
34 #include "chrome/browser/history/history_backend.h" | 33 #include "chrome/browser/history/history_backend.h" |
35 #include "chrome/browser/history/history_notifications.h" | |
36 #include "chrome/browser/history/in_memory_history_backend.h" | 34 #include "chrome/browser/history/in_memory_history_backend.h" |
37 #include "chrome/browser/history/in_memory_url_index.h" | 35 #include "chrome/browser/history/in_memory_url_index.h" |
38 #include "chrome/browser/history/top_sites.h" | 36 #include "chrome/browser/history/top_sites.h" |
39 #include "chrome/browser/history/web_history_service.h" | 37 #include "chrome/browser/history/web_history_service.h" |
40 #include "chrome/browser/history/web_history_service_factory.h" | 38 #include "chrome/browser/history/web_history_service_factory.h" |
41 #include "chrome/browser/profiles/profile.h" | 39 #include "chrome/browser/profiles/profile.h" |
42 #include "chrome/common/chrome_constants.h" | 40 #include "chrome/common/chrome_constants.h" |
43 #include "chrome/common/chrome_switches.h" | 41 #include "chrome/common/chrome_switches.h" |
44 #include "chrome/common/importer/imported_favicon_usage.h" | 42 #include "chrome/common/importer/imported_favicon_usage.h" |
45 #include "chrome/common/pref_names.h" | 43 #include "chrome/common/pref_names.h" |
46 #include "chrome/common/url_constants.h" | 44 #include "chrome/common/url_constants.h" |
47 #include "components/dom_distiller/core/url_constants.h" | 45 #include "components/dom_distiller/core/url_constants.h" |
48 #include "components/history/core/browser/download_row.h" | 46 #include "components/history/core/browser/download_row.h" |
49 #include "components/history/core/browser/history_client.h" | 47 #include "components/history/core/browser/history_client.h" |
50 #include "components/history/core/browser/history_database_params.h" | 48 #include "components/history/core/browser/history_database_params.h" |
51 #include "components/history/core/browser/history_service_observer.h" | 49 #include "components/history/core/browser/history_service_observer.h" |
52 #include "components/history/core/browser/history_types.h" | 50 #include "components/history/core/browser/history_types.h" |
53 #include "components/history/core/browser/in_memory_database.h" | 51 #include "components/history/core/browser/in_memory_database.h" |
54 #include "components/history/core/browser/keyword_search_term.h" | 52 #include "components/history/core/browser/keyword_search_term.h" |
55 #include "components/history/core/browser/visit_database.h" | 53 #include "components/history/core/browser/visit_database.h" |
56 #include "components/history/core/browser/visit_filter.h" | 54 #include "components/history/core/browser/visit_filter.h" |
57 #include "components/history/core/common/thumbnail_score.h" | 55 #include "components/history/core/common/thumbnail_score.h" |
58 #include "components/visitedlink/browser/visitedlink_master.h" | 56 #include "components/visitedlink/browser/visitedlink_master.h" |
59 #include "content/public/browser/browser_thread.h" | 57 #include "content/public/browser/browser_thread.h" |
60 #include "content/public/browser/download_item.h" | 58 #include "content/public/browser/download_item.h" |
61 #include "content/public/browser/notification_service.h" | |
62 #include "sync/api/sync_error_factory.h" | 59 #include "sync/api/sync_error_factory.h" |
63 #include "third_party/skia/include/core/SkBitmap.h" | 60 #include "third_party/skia/include/core/SkBitmap.h" |
64 | 61 |
65 using base::Time; | 62 using base::Time; |
66 using history::HistoryBackend; | 63 using history::HistoryBackend; |
67 using history::KeywordID; | 64 using history::KeywordID; |
68 | 65 |
69 namespace { | 66 namespace { |
70 | 67 |
71 static const char* kHistoryThreadName = "Chrome_HistoryThread"; | 68 static const char* kHistoryThreadName = "Chrome_HistoryThread"; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 } // namespace | 121 } // namespace |
125 | 122 |
126 // Sends messages from the backend to us on the main thread. This must be a | 123 // Sends messages from the backend to us on the main thread. This must be a |
127 // separate class from the history service so that it can hold a reference to | 124 // separate class from the history service so that it can hold a reference to |
128 // the history service (otherwise we would have to manually AddRef and | 125 // the history service (otherwise we would have to manually AddRef and |
129 // Release when the Backend has a reference to us). | 126 // Release when the Backend has a reference to us). |
130 class HistoryService::BackendDelegate : public HistoryBackend::Delegate { | 127 class HistoryService::BackendDelegate : public HistoryBackend::Delegate { |
131 public: | 128 public: |
132 BackendDelegate( | 129 BackendDelegate( |
133 const base::WeakPtr<HistoryService>& history_service, | 130 const base::WeakPtr<HistoryService>& history_service, |
134 const scoped_refptr<base::SequencedTaskRunner>& service_task_runner, | 131 const scoped_refptr<base::SequencedTaskRunner>& service_task_runner) |
135 Profile* profile) | |
136 : history_service_(history_service), | 132 : history_service_(history_service), |
137 service_task_runner_(service_task_runner), | 133 service_task_runner_(service_task_runner) {} |
138 profile_(profile) { | |
139 } | |
140 | 134 |
141 void NotifyProfileError(sql::InitStatus init_status) override { | 135 void NotifyProfileError(sql::InitStatus init_status) override { |
142 // Send to the history service on the main thread. | 136 // Send to the history service on the main thread. |
143 service_task_runner_->PostTask( | 137 service_task_runner_->PostTask( |
144 FROM_HERE, | 138 FROM_HERE, |
145 base::Bind(&HistoryService::NotifyProfileError, history_service_, | 139 base::Bind(&HistoryService::NotifyProfileError, history_service_, |
146 init_status)); | 140 init_status)); |
147 } | 141 } |
148 | 142 |
149 void SetInMemoryBackend( | 143 void SetInMemoryBackend( |
(...skipping 27 matching lines...) Expand all Loading... |
177 base::Bind(&HistoryService::NotifyURLVisited, | 171 base::Bind(&HistoryService::NotifyURLVisited, |
178 history_service_, | 172 history_service_, |
179 transition, | 173 transition, |
180 row, | 174 row, |
181 redirects, | 175 redirects, |
182 visit_time)); | 176 visit_time)); |
183 } | 177 } |
184 | 178 |
185 void NotifyURLsModified(const history::URLRows& changed_urls) override { | 179 void NotifyURLsModified(const history::URLRows& changed_urls) override { |
186 service_task_runner_->PostTask( | 180 service_task_runner_->PostTask( |
| 181 FROM_HERE, base::Bind(&HistoryService::NotifyURLsModified, |
| 182 history_service_, changed_urls)); |
| 183 } |
| 184 |
| 185 void NotifyURLsDeleted(bool all_history, |
| 186 bool expired, |
| 187 const history::URLRows& deleted_rows, |
| 188 const std::set<GURL>& favicon_urls) override { |
| 189 service_task_runner_->PostTask( |
187 FROM_HERE, | 190 FROM_HERE, |
188 base::Bind(&HistoryService::NotifyURLsModified, | 191 base::Bind(&HistoryService::NotifyURLsDeleted, history_service_, |
189 history_service_, | 192 all_history, expired, deleted_rows, favicon_urls)); |
190 changed_urls)); | |
191 } | 193 } |
192 | 194 |
193 void NotifyKeywordSearchTermUpdated(const history::URLRow& row, | 195 void NotifyKeywordSearchTermUpdated(const history::URLRow& row, |
194 KeywordID keyword_id, | 196 KeywordID keyword_id, |
195 const base::string16& term) override { | 197 const base::string16& term) override { |
196 service_task_runner_->PostTask( | 198 service_task_runner_->PostTask( |
197 FROM_HERE, base::Bind(&HistoryService::NotifyKeywordSearchTermUpdated, | 199 FROM_HERE, base::Bind(&HistoryService::NotifyKeywordSearchTermUpdated, |
198 history_service_, row, keyword_id, term)); | 200 history_service_, row, keyword_id, term)); |
199 } | 201 } |
200 | 202 |
201 void NotifyKeywordSearchTermDeleted(history::URLID url_id) override { | 203 void NotifyKeywordSearchTermDeleted(history::URLID url_id) override { |
202 service_task_runner_->PostTask( | 204 service_task_runner_->PostTask( |
203 FROM_HERE, base::Bind(&HistoryService::NotifyKeywordSearchTermDeleted, | 205 FROM_HERE, base::Bind(&HistoryService::NotifyKeywordSearchTermDeleted, |
204 history_service_, url_id)); | 206 history_service_, url_id)); |
205 } | 207 } |
206 | 208 |
207 void BroadcastNotifications( | |
208 int type, | |
209 scoped_ptr<history::HistoryDetails> details) override { | |
210 // Send the notification on the history thread. | |
211 if (content::NotificationService::current()) { | |
212 content::Details<history::HistoryDetails> det(details.get()); | |
213 content::NotificationService::current()->Notify( | |
214 type, content::Source<Profile>(profile_), det); | |
215 } | |
216 // Send the notification to the history service on the main thread. | |
217 service_task_runner_->PostTask( | |
218 FROM_HERE, | |
219 base::Bind(&HistoryService::BroadcastNotificationsHelper, | |
220 history_service_, type, base::Passed(&details))); | |
221 } | |
222 | |
223 void DBLoaded() override { | 209 void DBLoaded() override { |
224 service_task_runner_->PostTask( | 210 service_task_runner_->PostTask( |
225 FROM_HERE, | 211 FROM_HERE, |
226 base::Bind(&HistoryService::OnDBLoaded, history_service_)); | 212 base::Bind(&HistoryService::OnDBLoaded, history_service_)); |
227 } | 213 } |
228 | 214 |
229 private: | 215 private: |
230 const base::WeakPtr<HistoryService> history_service_; | 216 const base::WeakPtr<HistoryService> history_service_; |
231 const scoped_refptr<base::SequencedTaskRunner> service_task_runner_; | 217 const scoped_refptr<base::SequencedTaskRunner> service_task_runner_; |
232 Profile* const profile_; | |
233 }; | 218 }; |
234 | 219 |
235 // The history thread is intentionally not a BrowserThread because the | 220 // The history thread is intentionally not a BrowserThread because the |
236 // sync integration unit tests depend on being able to create more than one | 221 // sync integration unit tests depend on being able to create more than one |
237 // history thread. | 222 // history thread. |
238 HistoryService::HistoryService() | 223 HistoryService::HistoryService() |
239 : thread_(new base::Thread(kHistoryThreadName)), | 224 : thread_(new base::Thread(kHistoryThreadName)), |
240 history_client_(NULL), | 225 history_client_(NULL), |
241 profile_(NULL), | 226 profile_(NULL), |
242 backend_loaded_(false), | 227 backend_loaded_(false), |
243 no_db_(false), | 228 no_db_(false), |
244 weak_ptr_factory_(this) { | 229 weak_ptr_factory_(this) { |
245 } | 230 } |
246 | 231 |
247 HistoryService::HistoryService(history::HistoryClient* client, Profile* profile) | 232 HistoryService::HistoryService(history::HistoryClient* client, Profile* profile) |
248 : thread_(new base::Thread(kHistoryThreadName)), | 233 : thread_(new base::Thread(kHistoryThreadName)), |
249 history_client_(client), | 234 history_client_(client), |
250 profile_(profile), | 235 profile_(profile), |
251 visitedlink_master_(new visitedlink::VisitedLinkMaster( | 236 visitedlink_master_(new visitedlink::VisitedLinkMaster( |
252 profile, this, true)), | 237 profile, this, true)), |
253 backend_loaded_(false), | 238 backend_loaded_(false), |
254 no_db_(false), | 239 no_db_(false), |
255 weak_ptr_factory_(this) { | 240 weak_ptr_factory_(this) { |
256 DCHECK(profile_); | 241 DCHECK(profile_); |
257 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | |
258 content::Source<Profile>(profile_)); | |
259 } | 242 } |
260 | 243 |
261 HistoryService::~HistoryService() { | 244 HistoryService::~HistoryService() { |
262 DCHECK(thread_checker_.CalledOnValidThread()); | 245 DCHECK(thread_checker_.CalledOnValidThread()); |
263 // Shutdown the backend. This does nothing if Cleanup was already invoked. | 246 // Shutdown the backend. This does nothing if Cleanup was already invoked. |
264 Cleanup(); | 247 Cleanup(); |
265 } | 248 } |
266 | 249 |
267 bool HistoryService::BackendLoaded() { | 250 bool HistoryService::BackendLoaded() { |
268 DCHECK(thread_checker_.CalledOnValidThread()); | 251 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 } | 931 } |
949 | 932 |
950 // Delete the thread, which joins with the background thread. We defensively | 933 // Delete the thread, which joins with the background thread. We defensively |
951 // NULL the pointer before deleting it in case somebody tries to use it | 934 // NULL the pointer before deleting it in case somebody tries to use it |
952 // during shutdown, but this shouldn't happen. | 935 // during shutdown, but this shouldn't happen. |
953 base::Thread* thread = thread_; | 936 base::Thread* thread = thread_; |
954 thread_ = NULL; | 937 thread_ = NULL; |
955 delete thread; | 938 delete thread; |
956 } | 939 } |
957 | 940 |
958 void HistoryService::Observe(int type, | |
959 const content::NotificationSource& source, | |
960 const content::NotificationDetails& details) { | |
961 DCHECK(thread_checker_.CalledOnValidThread()); | |
962 if (!thread_) | |
963 return; | |
964 | |
965 switch (type) { | |
966 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { | |
967 // Update the visited link system for deleted URLs. We will update the | |
968 // visited link system for added URLs as soon as we get the add | |
969 // notification (we don't have to wait for the backend, which allows us to | |
970 // be faster to update the state). | |
971 // | |
972 // For deleted URLs, we don't typically know what will be deleted since | |
973 // delete notifications are by time. We would also like to be more | |
974 // respectful of privacy and never tell the user something is gone when it | |
975 // isn't. Therefore, we update the delete URLs after the fact. | |
976 if (visitedlink_master_) { | |
977 content::Details<history::URLsDeletedDetails> deleted_details(details); | |
978 | |
979 if (deleted_details->all_history) { | |
980 visitedlink_master_->DeleteAllURLs(); | |
981 } else { | |
982 URLIteratorFromURLRows iterator(deleted_details->rows); | |
983 visitedlink_master_->DeleteURLs(&iterator); | |
984 } | |
985 } | |
986 break; | |
987 } | |
988 | |
989 default: | |
990 NOTREACHED(); | |
991 } | |
992 } | |
993 | |
994 void HistoryService::RebuildTable( | 941 void HistoryService::RebuildTable( |
995 const scoped_refptr<URLEnumerator>& enumerator) { | 942 const scoped_refptr<URLEnumerator>& enumerator) { |
996 DCHECK(thread_) << "History service being called after cleanup"; | 943 DCHECK(thread_) << "History service being called after cleanup"; |
997 DCHECK(thread_checker_.CalledOnValidThread()); | 944 DCHECK(thread_checker_.CalledOnValidThread()); |
998 ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator); | 945 ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator); |
999 } | 946 } |
1000 | 947 |
1001 bool HistoryService::Init( | 948 bool HistoryService::Init( |
1002 bool no_db, | 949 bool no_db, |
1003 const history::HistoryDatabaseParams& history_database_params) { | 950 const history::HistoryDatabaseParams& history_database_params) { |
(...skipping 11 matching lines...) Expand all Loading... |
1015 | 962 |
1016 if (profile_) { | 963 if (profile_) { |
1017 std::string languages = | 964 std::string languages = |
1018 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); | 965 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); |
1019 in_memory_url_index_.reset(new history::InMemoryURLIndex( | 966 in_memory_url_index_.reset(new history::InMemoryURLIndex( |
1020 profile_, this, history_dir_, languages, history_client_)); | 967 profile_, this, history_dir_, languages, history_client_)); |
1021 in_memory_url_index_->Init(); | 968 in_memory_url_index_->Init(); |
1022 } | 969 } |
1023 | 970 |
1024 // Create the history backend. | 971 // Create the history backend. |
1025 scoped_refptr<HistoryBackend> backend( | 972 scoped_refptr<HistoryBackend> backend(new HistoryBackend( |
1026 new HistoryBackend(history_dir_, | 973 history_dir_, new BackendDelegate(weak_ptr_factory_.GetWeakPtr(), |
1027 new BackendDelegate( | 974 base::ThreadTaskRunnerHandle::Get()), |
1028 weak_ptr_factory_.GetWeakPtr(), | 975 history_client_)); |
1029 base::ThreadTaskRunnerHandle::Get(), | |
1030 profile_), | |
1031 history_client_)); | |
1032 history_backend_.swap(backend); | 976 history_backend_.swap(backend); |
1033 | 977 |
1034 // There may not be a profile when unit testing. | 978 // There may not be a profile when unit testing. |
1035 std::string languages; | 979 std::string languages; |
1036 if (profile_) { | 980 if (profile_) { |
1037 PrefService* prefs = profile_->GetPrefs(); | 981 PrefService* prefs = profile_->GetPrefs(); |
1038 languages = prefs->GetString(prefs::kAcceptLanguages); | 982 languages = prefs->GetString(prefs::kAcceptLanguages); |
1039 } | 983 } |
1040 | 984 |
1041 ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init, languages, no_db_, | 985 ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init, languages, no_db_, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1135 delete_directive); | 1079 delete_directive); |
1136 } | 1080 } |
1137 | 1081 |
1138 void HistoryService::SetInMemoryBackend( | 1082 void HistoryService::SetInMemoryBackend( |
1139 scoped_ptr<history::InMemoryHistoryBackend> mem_backend) { | 1083 scoped_ptr<history::InMemoryHistoryBackend> mem_backend) { |
1140 DCHECK(thread_checker_.CalledOnValidThread()); | 1084 DCHECK(thread_checker_.CalledOnValidThread()); |
1141 DCHECK(!in_memory_backend_) << "Setting mem DB twice"; | 1085 DCHECK(!in_memory_backend_) << "Setting mem DB twice"; |
1142 in_memory_backend_.reset(mem_backend.release()); | 1086 in_memory_backend_.reset(mem_backend.release()); |
1143 | 1087 |
1144 // The database requires additional initialization once we own it. | 1088 // The database requires additional initialization once we own it. |
1145 in_memory_backend_->AttachToHistoryService(profile_, this); | 1089 in_memory_backend_->AttachToHistoryService(this); |
1146 } | 1090 } |
1147 | 1091 |
1148 void HistoryService::NotifyProfileError(sql::InitStatus init_status) { | 1092 void HistoryService::NotifyProfileError(sql::InitStatus init_status) { |
1149 DCHECK(thread_checker_.CalledOnValidThread()); | 1093 DCHECK(thread_checker_.CalledOnValidThread()); |
1150 if (history_client_) | 1094 if (history_client_) |
1151 history_client_->NotifyProfileError(init_status); | 1095 history_client_->NotifyProfileError(init_status); |
1152 } | 1096 } |
1153 | 1097 |
1154 void HistoryService::DeleteURL(const GURL& url) { | 1098 void HistoryService::DeleteURL(const GURL& url) { |
1155 DCHECK(thread_) << "History service being called after cleanup"; | 1099 DCHECK(thread_) << "History service being called after cleanup"; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 // | 1164 // |
1221 // TODO(davidben): |callback| should not run until this operation completes | 1165 // TODO(davidben): |callback| should not run until this operation completes |
1222 // too. | 1166 // too. |
1223 web_history->ExpireHistoryBetween( | 1167 web_history->ExpireHistoryBetween( |
1224 restrict_urls, begin_time, end_time, | 1168 restrict_urls, begin_time, end_time, |
1225 base::Bind(&ExpireWebHistoryComplete)); | 1169 base::Bind(&ExpireWebHistoryComplete)); |
1226 } | 1170 } |
1227 ExpireHistoryBetween(restrict_urls, begin_time, end_time, callback, tracker); | 1171 ExpireHistoryBetween(restrict_urls, begin_time, end_time, callback, tracker); |
1228 } | 1172 } |
1229 | 1173 |
1230 void HistoryService::BroadcastNotificationsHelper( | |
1231 int type, | |
1232 scoped_ptr<history::HistoryDetails> details) { | |
1233 DCHECK(thread_checker_.CalledOnValidThread()); | |
1234 // TODO(evanm): this is currently necessitated by generate_profile, which | |
1235 // runs without a browser process. generate_profile should really create | |
1236 // a browser process, at which point this check can then be nuked. | |
1237 if (!g_browser_process) | |
1238 return; | |
1239 | |
1240 if (!thread_) | |
1241 return; | |
1242 | |
1243 // The source of all of our notifications is the profile. Note that this | |
1244 // pointer is NULL in unit tests. | |
1245 content::Source<Profile> source(profile_); | |
1246 | |
1247 // The details object just contains the pointer to the object that the | |
1248 // backend has allocated for us. The receiver of the notification will cast | |
1249 // this to the proper type. | |
1250 content::Details<history::HistoryDetails> det(details.get()); | |
1251 | |
1252 content::NotificationService::current()->Notify(type, source, det); | |
1253 } | |
1254 | |
1255 void HistoryService::OnDBLoaded() { | 1174 void HistoryService::OnDBLoaded() { |
1256 DCHECK(thread_checker_.CalledOnValidThread()); | 1175 DCHECK(thread_checker_.CalledOnValidThread()); |
1257 backend_loaded_ = true; | 1176 backend_loaded_ = true; |
1258 NotifyHistoryServiceLoaded(); | 1177 NotifyHistoryServiceLoaded(); |
1259 } | 1178 } |
1260 | 1179 |
1261 bool HistoryService::GetRowForURL(const GURL& url, history::URLRow* url_row) { | 1180 bool HistoryService::GetRowForURL(const GURL& url, history::URLRow* url_row) { |
1262 DCHECK(thread_checker_.CalledOnValidThread()); | 1181 DCHECK(thread_checker_.CalledOnValidThread()); |
1263 history::URLDatabase* db = InMemoryDatabase(); | 1182 history::URLDatabase* db = InMemoryDatabase(); |
1264 return db && (db->GetRowForURL(url, url_row) != 0); | 1183 return db && (db->GetRowForURL(url, url_row) != 0); |
(...skipping 15 matching lines...) Expand all Loading... |
1280 OnURLVisited(this, transition, row, redirects, visit_time)); | 1199 OnURLVisited(this, transition, row, redirects, visit_time)); |
1281 } | 1200 } |
1282 | 1201 |
1283 void HistoryService::NotifyURLsModified(const history::URLRows& changed_urls) { | 1202 void HistoryService::NotifyURLsModified(const history::URLRows& changed_urls) { |
1284 DCHECK(thread_checker_.CalledOnValidThread()); | 1203 DCHECK(thread_checker_.CalledOnValidThread()); |
1285 FOR_EACH_OBSERVER(history::HistoryServiceObserver, | 1204 FOR_EACH_OBSERVER(history::HistoryServiceObserver, |
1286 observers_, | 1205 observers_, |
1287 OnURLsModified(this, changed_urls)); | 1206 OnURLsModified(this, changed_urls)); |
1288 } | 1207 } |
1289 | 1208 |
| 1209 void HistoryService::NotifyURLsDeleted(bool all_history, |
| 1210 bool expired, |
| 1211 const history::URLRows& deleted_rows, |
| 1212 const std::set<GURL>& favicon_urls) { |
| 1213 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1214 if (!thread_) |
| 1215 return; |
| 1216 |
| 1217 // Update the visited link system for deleted URLs. We will update the |
| 1218 // visited link system for added URLs as soon as we get the add |
| 1219 // notification (we don't have to wait for the backend, which allows us to |
| 1220 // be faster to update the state). |
| 1221 // |
| 1222 // For deleted URLs, we don't typically know what will be deleted since |
| 1223 // delete notifications are by time. We would also like to be more |
| 1224 // respectful of privacy and never tell the user something is gone when it |
| 1225 // isn't. Therefore, we update the delete URLs after the fact. |
| 1226 if (visitedlink_master_) { |
| 1227 if (all_history) { |
| 1228 visitedlink_master_->DeleteAllURLs(); |
| 1229 } else { |
| 1230 URLIteratorFromURLRows iterator(deleted_rows); |
| 1231 visitedlink_master_->DeleteURLs(&iterator); |
| 1232 } |
| 1233 } |
| 1234 |
| 1235 FOR_EACH_OBSERVER( |
| 1236 history::HistoryServiceObserver, observers_, |
| 1237 OnURLsDeleted(this, all_history, expired, deleted_rows, favicon_urls)); |
| 1238 } |
| 1239 |
1290 void HistoryService::NotifyHistoryServiceLoaded() { | 1240 void HistoryService::NotifyHistoryServiceLoaded() { |
1291 DCHECK(thread_checker_.CalledOnValidThread()); | 1241 DCHECK(thread_checker_.CalledOnValidThread()); |
1292 FOR_EACH_OBSERVER(history::HistoryServiceObserver, observers_, | 1242 FOR_EACH_OBSERVER(history::HistoryServiceObserver, observers_, |
1293 OnHistoryServiceLoaded(this)); | 1243 OnHistoryServiceLoaded(this)); |
1294 } | 1244 } |
1295 | 1245 |
1296 void HistoryService::NotifyHistoryServiceBeingDeleted() { | 1246 void HistoryService::NotifyHistoryServiceBeingDeleted() { |
1297 DCHECK(thread_checker_.CalledOnValidThread()); | 1247 DCHECK(thread_checker_.CalledOnValidThread()); |
1298 FOR_EACH_OBSERVER(history::HistoryServiceObserver, observers_, | 1248 FOR_EACH_OBSERVER(history::HistoryServiceObserver, observers_, |
1299 HistoryServiceBeingDeleted(this)); | 1249 HistoryServiceBeingDeleted(this)); |
(...skipping 19 matching lines...) Expand all Loading... |
1319 const HistoryService::OnFaviconChangedCallback& callback) { | 1269 const HistoryService::OnFaviconChangedCallback& callback) { |
1320 DCHECK(thread_checker_.CalledOnValidThread()); | 1270 DCHECK(thread_checker_.CalledOnValidThread()); |
1321 return favicon_changed_callback_list_.Add(callback); | 1271 return favicon_changed_callback_list_.Add(callback); |
1322 } | 1272 } |
1323 | 1273 |
1324 void HistoryService::NotifyFaviconChanged( | 1274 void HistoryService::NotifyFaviconChanged( |
1325 const std::set<GURL>& changed_favicons) { | 1275 const std::set<GURL>& changed_favicons) { |
1326 DCHECK(thread_checker_.CalledOnValidThread()); | 1276 DCHECK(thread_checker_.CalledOnValidThread()); |
1327 favicon_changed_callback_list_.Notify(changed_favicons); | 1277 favicon_changed_callback_list_.Notify(changed_favicons); |
1328 } | 1278 } |
OLD | NEW |