| 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 15 matching lines...) Expand all Loading... |
| 26 #include "base/compiler_specific.h" | 26 #include "base/compiler_specific.h" |
| 27 #include "base/location.h" | 27 #include "base/location.h" |
| 28 #include "base/memory/ref_counted.h" | 28 #include "base/memory/ref_counted.h" |
| 29 #include "base/message_loop/message_loop.h" | 29 #include "base/message_loop/message_loop.h" |
| 30 #include "base/path_service.h" | 30 #include "base/path_service.h" |
| 31 #include "base/prefs/pref_service.h" | 31 #include "base/prefs/pref_service.h" |
| 32 #include "base/thread_task_runner_handle.h" | 32 #include "base/thread_task_runner_handle.h" |
| 33 #include "base/threading/thread.h" | 33 #include "base/threading/thread.h" |
| 34 #include "base/time/time.h" | 34 #include "base/time/time.h" |
| 35 #include "chrome/browser/autocomplete/history_url_provider.h" | 35 #include "chrome/browser/autocomplete/history_url_provider.h" |
| 36 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | |
| 37 #include "chrome/browser/browser_process.h" | 36 #include "chrome/browser/browser_process.h" |
| 38 #include "chrome/browser/chrome_notification_types.h" | 37 #include "chrome/browser/chrome_notification_types.h" |
| 39 #include "chrome/browser/history/download_row.h" | 38 #include "chrome/browser/history/download_row.h" |
| 40 #include "chrome/browser/history/history_backend.h" | 39 #include "chrome/browser/history/history_backend.h" |
| 41 #include "chrome/browser/history/history_notifications.h" | 40 #include "chrome/browser/history/history_notifications.h" |
| 42 #include "chrome/browser/history/history_types.h" | 41 #include "chrome/browser/history/history_types.h" |
| 43 #include "chrome/browser/history/in_memory_database.h" | 42 #include "chrome/browser/history/in_memory_database.h" |
| 44 #include "chrome/browser/history/in_memory_history_backend.h" | 43 #include "chrome/browser/history/in_memory_history_backend.h" |
| 45 #include "chrome/browser/history/in_memory_url_index.h" | 44 #include "chrome/browser/history/in_memory_url_index.h" |
| 46 #include "chrome/browser/history/top_sites.h" | 45 #include "chrome/browser/history/top_sites.h" |
| 47 #include "chrome/browser/history/visit_database.h" | 46 #include "chrome/browser/history/visit_database.h" |
| 48 #include "chrome/browser/history/visit_filter.h" | 47 #include "chrome/browser/history/visit_filter.h" |
| 49 #include "chrome/browser/history/web_history_service.h" | 48 #include "chrome/browser/history/web_history_service.h" |
| 50 #include "chrome/browser/history/web_history_service_factory.h" | 49 #include "chrome/browser/history/web_history_service_factory.h" |
| 51 #include "chrome/browser/profiles/profile.h" | 50 #include "chrome/browser/profiles/profile.h" |
| 52 #include "chrome/browser/ui/profile_error_dialog.h" | 51 #include "chrome/browser/ui/profile_error_dialog.h" |
| 53 #include "chrome/common/chrome_constants.h" | 52 #include "chrome/common/chrome_constants.h" |
| 54 #include "chrome/common/chrome_switches.h" | 53 #include "chrome/common/chrome_switches.h" |
| 55 #include "chrome/common/importer/imported_favicon_usage.h" | 54 #include "chrome/common/importer/imported_favicon_usage.h" |
| 56 #include "chrome/common/pref_names.h" | 55 #include "chrome/common/pref_names.h" |
| 57 #include "chrome/common/thumbnail_score.h" | 56 #include "chrome/common/thumbnail_score.h" |
| 58 #include "chrome/common/url_constants.h" | 57 #include "chrome/common/url_constants.h" |
| 59 #include "components/bookmarks/browser/bookmark_model.h" | 58 #include "components/history/core/browser/history_client.h" |
| 60 #include "components/visitedlink/browser/visitedlink_master.h" | 59 #include "components/visitedlink/browser/visitedlink_master.h" |
| 61 #include "content/public/browser/browser_thread.h" | 60 #include "content/public/browser/browser_thread.h" |
| 62 #include "content/public/browser/download_item.h" | 61 #include "content/public/browser/download_item.h" |
| 63 #include "content/public/browser/notification_service.h" | 62 #include "content/public/browser/notification_service.h" |
| 64 #include "grit/chromium_strings.h" | 63 #include "grit/chromium_strings.h" |
| 65 #include "grit/generated_resources.h" | 64 #include "grit/generated_resources.h" |
| 66 #include "sync/api/sync_error_factory.h" | 65 #include "sync/api/sync_error_factory.h" |
| 67 #include "third_party/skia/include/core/SkBitmap.h" | 66 #include "third_party/skia/include/core/SkBitmap.h" |
| 68 | 67 |
| 69 using base::Time; | 68 using base::Time; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 const scoped_refptr<base::SequencedTaskRunner> service_task_runner_; | 184 const scoped_refptr<base::SequencedTaskRunner> service_task_runner_; |
| 186 Profile* const profile_; | 185 Profile* const profile_; |
| 187 }; | 186 }; |
| 188 | 187 |
| 189 // The history thread is intentionally not a BrowserThread because the | 188 // The history thread is intentionally not a BrowserThread because the |
| 190 // sync integration unit tests depend on being able to create more than one | 189 // sync integration unit tests depend on being able to create more than one |
| 191 // history thread. | 190 // history thread. |
| 192 HistoryService::HistoryService() | 191 HistoryService::HistoryService() |
| 193 : weak_ptr_factory_(this), | 192 : weak_ptr_factory_(this), |
| 194 thread_(new base::Thread(kHistoryThreadName)), | 193 thread_(new base::Thread(kHistoryThreadName)), |
| 194 history_client_(NULL), |
| 195 profile_(NULL), | 195 profile_(NULL), |
| 196 backend_loaded_(false), | 196 backend_loaded_(false), |
| 197 bookmark_service_(NULL), | |
| 198 no_db_(false) { | 197 no_db_(false) { |
| 199 } | 198 } |
| 200 | 199 |
| 201 HistoryService::HistoryService(Profile* profile) | 200 HistoryService::HistoryService(history::HistoryClient* client, Profile* profile) |
| 202 : weak_ptr_factory_(this), | 201 : weak_ptr_factory_(this), |
| 203 thread_(new base::Thread(kHistoryThreadName)), | 202 thread_(new base::Thread(kHistoryThreadName)), |
| 203 history_client_(client), |
| 204 profile_(profile), | 204 profile_(profile), |
| 205 visitedlink_master_(new visitedlink::VisitedLinkMaster( | 205 visitedlink_master_(new visitedlink::VisitedLinkMaster( |
| 206 profile, this, true)), | 206 profile, this, true)), |
| 207 backend_loaded_(false), | 207 backend_loaded_(false), |
| 208 bookmark_service_(NULL), | |
| 209 no_db_(false) { | 208 no_db_(false) { |
| 210 DCHECK(profile_); | 209 DCHECK(profile_); |
| 211 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 210 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
| 212 content::Source<Profile>(profile_)); | 211 content::Source<Profile>(profile_)); |
| 213 registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_REMOVED, | 212 registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_REMOVED, |
| 214 content::Source<Profile>(profile_)); | 213 content::Source<Profile>(profile_)); |
| 215 } | 214 } |
| 216 | 215 |
| 217 HistoryService::~HistoryService() { | 216 HistoryService::~HistoryService() { |
| 218 DCHECK(thread_checker_.CalledOnValidThread()); | 217 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 return false; | 318 return false; |
| 320 *visit_count = url_row.visit_count(); | 319 *visit_count = url_row.visit_count(); |
| 321 return true; | 320 return true; |
| 322 } | 321 } |
| 323 | 322 |
| 324 history::TypedUrlSyncableService* HistoryService::GetTypedUrlSyncableService() | 323 history::TypedUrlSyncableService* HistoryService::GetTypedUrlSyncableService() |
| 325 const { | 324 const { |
| 326 return history_backend_->GetTypedUrlSyncableService(); | 325 return history_backend_->GetTypedUrlSyncableService(); |
| 327 } | 326 } |
| 328 | 327 |
| 329 void HistoryService::Shutdown() { | |
| 330 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 331 // It's possible that bookmarks haven't loaded and history is waiting for | |
| 332 // bookmarks to complete loading. In such a situation history can't shutdown | |
| 333 // (meaning if we invoked history_service_->Cleanup now, we would | |
| 334 // deadlock). To break the deadlock we tell BookmarkModel it's about to be | |
| 335 // deleted so that it can release the signal history is waiting on, allowing | |
| 336 // history to shutdown (history_service_->Cleanup to complete). In such a | |
| 337 // scenario history sees an incorrect view of bookmarks, but it's better | |
| 338 // than a deadlock. | |
| 339 BookmarkModel* bookmark_model = static_cast<BookmarkModel*>( | |
| 340 BookmarkModelFactory::GetForProfileIfExists(profile_)); | |
| 341 if (bookmark_model) | |
| 342 bookmark_model->Shutdown(); | |
| 343 | |
| 344 Cleanup(); | |
| 345 } | |
| 346 | |
| 347 void HistoryService::SetKeywordSearchTermsForURL(const GURL& url, | 328 void HistoryService::SetKeywordSearchTermsForURL(const GURL& url, |
| 348 TemplateURLID keyword_id, | 329 TemplateURLID keyword_id, |
| 349 const base::string16& term) { | 330 const base::string16& term) { |
| 350 DCHECK(thread_checker_.CalledOnValidThread()); | 331 DCHECK(thread_checker_.CalledOnValidThread()); |
| 351 ScheduleAndForget(PRIORITY_UI, | 332 ScheduleAndForget(PRIORITY_UI, |
| 352 &HistoryBackend::SetKeywordSearchTermsForURL, | 333 &HistoryBackend::SetKeywordSearchTermsForURL, |
| 353 url, keyword_id, term); | 334 url, keyword_id, term); |
| 354 } | 335 } |
| 355 | 336 |
| 356 void HistoryService::DeleteAllSearchTermsForKeyword( | 337 void HistoryService::DeleteAllSearchTermsForKeyword( |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 NOTREACHED(); | 882 NOTREACHED(); |
| 902 } | 883 } |
| 903 } | 884 } |
| 904 | 885 |
| 905 void HistoryService::RebuildTable( | 886 void HistoryService::RebuildTable( |
| 906 const scoped_refptr<URLEnumerator>& enumerator) { | 887 const scoped_refptr<URLEnumerator>& enumerator) { |
| 907 DCHECK(thread_checker_.CalledOnValidThread()); | 888 DCHECK(thread_checker_.CalledOnValidThread()); |
| 908 ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator); | 889 ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator); |
| 909 } | 890 } |
| 910 | 891 |
| 911 bool HistoryService::Init(const base::FilePath& history_dir, | 892 bool HistoryService::Init(const base::FilePath& history_dir, bool no_db) { |
| 912 BookmarkService* bookmark_service, | |
| 913 bool no_db) { | |
| 914 DCHECK(thread_checker_.CalledOnValidThread()); | 893 DCHECK(thread_checker_.CalledOnValidThread()); |
| 915 if (!thread_->Start()) { | 894 if (!thread_->Start()) { |
| 916 Cleanup(); | 895 Cleanup(); |
| 917 return false; | 896 return false; |
| 918 } | 897 } |
| 919 | 898 |
| 920 history_dir_ = history_dir; | 899 history_dir_ = history_dir; |
| 921 bookmark_service_ = bookmark_service; | |
| 922 no_db_ = no_db; | 900 no_db_ = no_db; |
| 923 | 901 |
| 924 if (profile_) { | 902 if (profile_) { |
| 925 std::string languages = | 903 std::string languages = |
| 926 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); | 904 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); |
| 927 in_memory_url_index_.reset( | 905 in_memory_url_index_.reset(new history::InMemoryURLIndex( |
| 928 new history::InMemoryURLIndex(profile_, history_dir_, languages)); | 906 profile_, history_dir_, languages, history_client_)); |
| 929 in_memory_url_index_->Init(); | 907 in_memory_url_index_->Init(); |
| 930 } | 908 } |
| 931 | 909 |
| 932 // Create the history backend. | 910 // Create the history backend. |
| 933 scoped_refptr<HistoryBackend> backend( | 911 scoped_refptr<HistoryBackend> backend( |
| 934 new HistoryBackend(history_dir_, | 912 new HistoryBackend(history_dir_, |
| 935 new BackendDelegate( | 913 new BackendDelegate( |
| 936 weak_ptr_factory_.GetWeakPtr(), | 914 weak_ptr_factory_.GetWeakPtr(), |
| 937 base::ThreadTaskRunnerHandle::Get(), | 915 base::ThreadTaskRunnerHandle::Get(), |
| 938 profile_), | 916 profile_), |
| 939 bookmark_service_)); | 917 history_client_)); |
| 940 history_backend_.swap(backend); | 918 history_backend_.swap(backend); |
| 941 | 919 |
| 942 // There may not be a profile when unit testing. | 920 // There may not be a profile when unit testing. |
| 943 std::string languages; | 921 std::string languages; |
| 944 if (profile_) { | 922 if (profile_) { |
| 945 PrefService* prefs = profile_->GetPrefs(); | 923 PrefService* prefs = profile_->GetPrefs(); |
| 946 languages = prefs->GetString(prefs::kAcceptLanguages); | 924 languages = prefs->GetString(prefs::kAcceptLanguages); |
| 947 } | 925 } |
| 948 ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init, languages, no_db_); | 926 ScheduleAndForget(PRIORITY_UI, &HistoryBackend::Init, languages, no_db_); |
| 949 | 927 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 DCHECK(thread_checker_.CalledOnValidThread()); | 1164 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1187 visit_database_observers_.RemoveObserver(observer); | 1165 visit_database_observers_.RemoveObserver(observer); |
| 1188 } | 1166 } |
| 1189 | 1167 |
| 1190 void HistoryService::NotifyVisitDBObserversOnAddVisit( | 1168 void HistoryService::NotifyVisitDBObserversOnAddVisit( |
| 1191 const history::BriefVisitInfo& info) { | 1169 const history::BriefVisitInfo& info) { |
| 1192 DCHECK(thread_checker_.CalledOnValidThread()); | 1170 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1193 FOR_EACH_OBSERVER(history::VisitDatabaseObserver, visit_database_observers_, | 1171 FOR_EACH_OBSERVER(history::VisitDatabaseObserver, visit_database_observers_, |
| 1194 OnAddVisit(info)); | 1172 OnAddVisit(info)); |
| 1195 } | 1173 } |
| OLD | NEW |