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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 int* id) { | 104 int* id) { |
105 callback.Run(*id); | 105 callback.Run(*id); |
106 } | 106 } |
107 | 107 |
108 void RunWithFaviconResults( | 108 void RunWithFaviconResults( |
109 const FaviconService::FaviconResultsCallback& callback, | 109 const FaviconService::FaviconResultsCallback& callback, |
110 const HistoryBackend::FaviconResults* results) { | 110 const HistoryBackend::FaviconResults* results) { |
111 callback.Run(results->bitmap_results, results->size_map); | 111 callback.Run(results->bitmap_results, results->size_map); |
112 } | 112 } |
113 | 113 |
| 114 // Extract history::URLRows into GURLs for VisitedLinkMaster. |
| 115 class URLIteratorFromURLRows : public VisitedLinkMaster::URLIterator { |
| 116 public: |
| 117 explicit URLIteratorFromURLRows(const history::URLRows& url_rows) |
| 118 : itr_(url_rows.begin()), |
| 119 end_(url_rows.end()) { |
| 120 } |
| 121 |
| 122 virtual const GURL& NextURL() { |
| 123 return (itr_++)->url(); |
| 124 } |
| 125 |
| 126 virtual bool HasNextURL() const { |
| 127 return itr_ != end_; |
| 128 } |
| 129 |
| 130 private: |
| 131 history::URLRows::const_iterator itr_; |
| 132 history::URLRows::const_iterator end_; |
| 133 |
| 134 DISALLOW_COPY_AND_ASSIGN(URLIteratorFromURLRows); |
| 135 }; |
| 136 |
114 } // namespace | 137 } // namespace |
115 | 138 |
116 // Sends messages from the backend to us on the main thread. This must be a | 139 // Sends messages from the backend to us on the main thread. This must be a |
117 // separate class from the history service so that it can hold a reference to | 140 // separate class from the history service so that it can hold a reference to |
118 // the history service (otherwise we would have to manually AddRef and | 141 // the history service (otherwise we would have to manually AddRef and |
119 // Release when the Backend has a reference to us). | 142 // Release when the Backend has a reference to us). |
120 class HistoryService::BackendDelegate : public HistoryBackend::Delegate { | 143 class HistoryService::BackendDelegate : public HistoryBackend::Delegate { |
121 public: | 144 public: |
122 BackendDelegate( | 145 BackendDelegate( |
123 const base::WeakPtr<HistoryService>& history_service, | 146 const base::WeakPtr<HistoryService>& history_service, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 current_backend_id_(-1), | 224 current_backend_id_(-1), |
202 bookmark_service_(NULL), | 225 bookmark_service_(NULL), |
203 no_db_(false), | 226 no_db_(false), |
204 needs_top_sites_migration_(false) { | 227 needs_top_sites_migration_(false) { |
205 } | 228 } |
206 | 229 |
207 HistoryService::HistoryService(Profile* profile) | 230 HistoryService::HistoryService(Profile* profile) |
208 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 231 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
209 thread_(new base::Thread(kHistoryThreadName)), | 232 thread_(new base::Thread(kHistoryThreadName)), |
210 profile_(profile), | 233 profile_(profile), |
| 234 visitedlink_master_(new VisitedLinkMaster( |
| 235 profile, ALLOW_THIS_IN_INITIALIZER_LIST(this))), |
211 backend_loaded_(false), | 236 backend_loaded_(false), |
212 current_backend_id_(-1), | 237 current_backend_id_(-1), |
213 bookmark_service_(NULL), | 238 bookmark_service_(NULL), |
214 no_db_(false), | 239 no_db_(false), |
215 needs_top_sites_migration_(false) { | 240 needs_top_sites_migration_(false) { |
216 DCHECK(profile_); | 241 DCHECK(profile_); |
217 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 242 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
218 content::Source<Profile>(profile_)); | 243 content::Source<Profile>(profile_)); |
219 registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_REMOVED, | 244 registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_REMOVED, |
220 content::Source<Profile>(profile_)); | 245 content::Source<Profile>(profile_)); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 DCHECK(thread_) << "History service being called after cleanup"; | 490 DCHECK(thread_) << "History service being called after cleanup"; |
466 | 491 |
467 // Filter out unwanted URLs. We don't add auto-subframe URLs. They are a | 492 // Filter out unwanted URLs. We don't add auto-subframe URLs. They are a |
468 // large part of history (think iframes for ads) and we never display them in | 493 // large part of history (think iframes for ads) and we never display them in |
469 // history UI. We will still add manual subframes, which are ones the user | 494 // history UI. We will still add manual subframes, which are ones the user |
470 // has clicked on to get. | 495 // has clicked on to get. |
471 if (!CanAddURL(add_page_args.url)) | 496 if (!CanAddURL(add_page_args.url)) |
472 return; | 497 return; |
473 | 498 |
474 // Add link & all redirects to visited link list. | 499 // Add link & all redirects to visited link list. |
475 VisitedLinkMaster* visited_links; | 500 if (visitedlink_master_) { |
476 if (profile_ && | 501 visitedlink_master_->AddURL(add_page_args.url); |
477 (visited_links = VisitedLinkMaster::FromProfile(profile_))) { | |
478 visited_links->AddURL(add_page_args.url); | |
479 | 502 |
480 if (!add_page_args.redirects.empty()) { | 503 if (!add_page_args.redirects.empty()) { |
481 // We should not be asked to add a page in the middle of a redirect chain. | 504 // We should not be asked to add a page in the middle of a redirect chain. |
482 DCHECK_EQ(add_page_args.url, | 505 DCHECK_EQ(add_page_args.url, |
483 add_page_args.redirects[add_page_args.redirects.size() - 1]); | 506 add_page_args.redirects[add_page_args.redirects.size() - 1]); |
484 | 507 |
485 // We need the !redirects.empty() condition above since size_t is unsigned | 508 // We need the !redirects.empty() condition above since size_t is unsigned |
486 // and will wrap around when we subtract one from a 0 size. | 509 // and will wrap around when we subtract one from a 0 size. |
487 for (size_t i = 0; i < add_page_args.redirects.size() - 1; i++) | 510 for (size_t i = 0; i < add_page_args.redirects.size() - 1; i++) |
488 visited_links->AddURL(add_page_args.redirects[i]); | 511 visitedlink_master_->AddURL(add_page_args.redirects[i]); |
489 } | 512 } |
490 } | 513 } |
491 | 514 |
492 ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::AddPage, add_page_args); | 515 ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::AddPage, add_page_args); |
493 } | 516 } |
494 | 517 |
495 void HistoryService::AddPageNoVisitForBookmark(const GURL& url, | 518 void HistoryService::AddPageNoVisitForBookmark(const GURL& url, |
496 const string16& title) { | 519 const string16& title) { |
497 DCHECK(thread_checker_.CalledOnValidThread()); | 520 DCHECK(thread_checker_.CalledOnValidThread()); |
498 if (!CanAddURL(url)) | 521 if (!CanAddURL(url)) |
(...skipping 24 matching lines...) Expand all Loading... |
523 int typed_count, | 546 int typed_count, |
524 Time last_visit, | 547 Time last_visit, |
525 bool hidden, | 548 bool hidden, |
526 history::VisitSource visit_source) { | 549 history::VisitSource visit_source) { |
527 DCHECK(thread_checker_.CalledOnValidThread()); | 550 DCHECK(thread_checker_.CalledOnValidThread()); |
528 // Filter out unwanted URLs. | 551 // Filter out unwanted URLs. |
529 if (!CanAddURL(url)) | 552 if (!CanAddURL(url)) |
530 return; | 553 return; |
531 | 554 |
532 // Add to the visited links system. | 555 // Add to the visited links system. |
533 VisitedLinkMaster* visited_links; | 556 if (visitedlink_master_) |
534 if (profile_ && | 557 visitedlink_master_->AddURL(url); |
535 (visited_links = VisitedLinkMaster::FromProfile(profile_))) { | |
536 visited_links->AddURL(url); | |
537 } | |
538 | 558 |
539 history::URLRow row(url); | 559 history::URLRow row(url); |
540 row.set_title(title); | 560 row.set_title(title); |
541 row.set_visit_count(visit_count); | 561 row.set_visit_count(visit_count); |
542 row.set_typed_count(typed_count); | 562 row.set_typed_count(typed_count); |
543 row.set_last_visit(last_visit); | 563 row.set_last_visit(last_visit); |
544 row.set_hidden(hidden); | 564 row.set_hidden(hidden); |
545 | 565 |
546 history::URLRows rows; | 566 history::URLRows rows; |
547 rows.push_back(row); | 567 rows.push_back(row); |
548 | 568 |
549 ScheduleAndForget(PRIORITY_NORMAL, | 569 ScheduleAndForget(PRIORITY_NORMAL, |
550 &HistoryBackend::AddPagesWithDetails, rows, visit_source); | 570 &HistoryBackend::AddPagesWithDetails, rows, visit_source); |
551 } | 571 } |
552 | 572 |
553 void HistoryService::AddPagesWithDetails(const history::URLRows& info, | 573 void HistoryService::AddPagesWithDetails(const history::URLRows& info, |
554 history::VisitSource visit_source) { | 574 history::VisitSource visit_source) { |
555 DCHECK(thread_checker_.CalledOnValidThread()); | 575 DCHECK(thread_checker_.CalledOnValidThread()); |
556 // Add to the visited links system. | 576 // Add to the visited links system. |
557 VisitedLinkMaster* visited_links; | 577 if (visitedlink_master_) { |
558 if (profile_ && | |
559 (visited_links = VisitedLinkMaster::FromProfile(profile_))) { | |
560 std::vector<GURL> urls; | 578 std::vector<GURL> urls; |
561 urls.reserve(info.size()); | 579 urls.reserve(info.size()); |
562 for (history::URLRows::const_iterator i = info.begin(); i != info.end(); | 580 for (history::URLRows::const_iterator i = info.begin(); i != info.end(); |
563 ++i) | 581 ++i) |
564 urls.push_back(i->url()); | 582 urls.push_back(i->url()); |
565 | 583 |
566 visited_links->AddURLs(urls); | 584 visitedlink_master_->AddURLs(urls); |
567 } | 585 } |
568 | 586 |
569 ScheduleAndForget(PRIORITY_NORMAL, | 587 ScheduleAndForget(PRIORITY_NORMAL, |
570 &HistoryBackend::AddPagesWithDetails, info, visit_source); | 588 &HistoryBackend::AddPagesWithDetails, info, visit_source); |
571 } | 589 } |
572 | 590 |
573 void HistoryService::SetPageContents(const GURL& url, | 591 void HistoryService::SetPageContents(const GURL& url, |
574 const string16& contents) { | 592 const string16& contents) { |
575 DCHECK(thread_checker_.CalledOnValidThread()); | 593 DCHECK(thread_checker_.CalledOnValidThread()); |
576 if (!CanAddURL(url)) | 594 if (!CanAddURL(url)) |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 old_page_url, new_page_url); | 731 old_page_url, new_page_url); |
714 } | 732 } |
715 | 733 |
716 void HistoryService::SetImportedFavicons( | 734 void HistoryService::SetImportedFavicons( |
717 const std::vector<history::ImportedFaviconUsage>& favicon_usage) { | 735 const std::vector<history::ImportedFaviconUsage>& favicon_usage) { |
718 DCHECK(thread_checker_.CalledOnValidThread()); | 736 DCHECK(thread_checker_.CalledOnValidThread()); |
719 ScheduleAndForget(PRIORITY_NORMAL, | 737 ScheduleAndForget(PRIORITY_NORMAL, |
720 &HistoryBackend::SetImportedFavicons, favicon_usage); | 738 &HistoryBackend::SetImportedFavicons, favicon_usage); |
721 } | 739 } |
722 | 740 |
723 void HistoryService::IterateURLs(URLEnumerator* enumerator) { | |
724 DCHECK(thread_checker_.CalledOnValidThread()); | |
725 ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator); | |
726 } | |
727 | |
728 HistoryService::Handle HistoryService::QueryURL( | 741 HistoryService::Handle HistoryService::QueryURL( |
729 const GURL& url, | 742 const GURL& url, |
730 bool want_visits, | 743 bool want_visits, |
731 CancelableRequestConsumerBase* consumer, | 744 CancelableRequestConsumerBase* consumer, |
732 const QueryURLCallback& callback) { | 745 const QueryURLCallback& callback) { |
733 DCHECK(thread_checker_.CalledOnValidThread()); | 746 DCHECK(thread_checker_.CalledOnValidThread()); |
734 return Schedule(PRIORITY_UI, &HistoryBackend::QueryURL, consumer, | 747 return Schedule(PRIORITY_UI, &HistoryBackend::QueryURL, consumer, |
735 new history::QueryURLRequest(callback), url, want_visits); | 748 new history::QueryURLRequest(callback), url, want_visits); |
736 } | 749 } |
737 | 750 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { | 908 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { |
896 // Update the visited link system for deleted URLs. We will update the | 909 // Update the visited link system for deleted URLs. We will update the |
897 // visited link system for added URLs as soon as we get the add | 910 // visited link system for added URLs as soon as we get the add |
898 // notification (we don't have to wait for the backend, which allows us to | 911 // notification (we don't have to wait for the backend, which allows us to |
899 // be faster to update the state). | 912 // be faster to update the state). |
900 // | 913 // |
901 // For deleted URLs, we don't typically know what will be deleted since | 914 // For deleted URLs, we don't typically know what will be deleted since |
902 // delete notifications are by time. We would also like to be more | 915 // delete notifications are by time. We would also like to be more |
903 // respectful of privacy and never tell the user something is gone when it | 916 // respectful of privacy and never tell the user something is gone when it |
904 // isn't. Therefore, we update the delete URLs after the fact. | 917 // isn't. Therefore, we update the delete URLs after the fact. |
905 if (!profile_) | 918 if (visitedlink_master_) { |
906 return; // No profile, probably unit testing. | 919 content::Details<history::URLsDeletedDetails> deleted_details(details); |
907 content::Details<history::URLsDeletedDetails> deleted_details(details); | 920 |
908 VisitedLinkMaster* visited_links = | 921 if (deleted_details->all_history) { |
909 VisitedLinkMaster::FromProfile(profile_); | 922 visitedlink_master_->DeleteAllURLs(); |
910 if (!visited_links) | 923 } else { |
911 return; // Nobody to update. | 924 URLIteratorFromURLRows iterator(deleted_details->rows); |
912 if (deleted_details->all_history) | 925 visitedlink_master_->DeleteURLs(&iterator); |
913 visited_links->DeleteAllURLs(); | 926 } |
914 else // Delete individual ones. | 927 } |
915 visited_links->DeleteURLs(deleted_details->rows); | |
916 break; | 928 break; |
917 } | 929 } |
918 | 930 |
919 case chrome::NOTIFICATION_TEMPLATE_URL_REMOVED: | 931 case chrome::NOTIFICATION_TEMPLATE_URL_REMOVED: |
920 DeleteAllSearchTermsForKeyword( | 932 DeleteAllSearchTermsForKeyword( |
921 *(content::Details<TemplateURLID>(details).ptr())); | 933 *(content::Details<TemplateURLID>(details).ptr())); |
922 break; | 934 break; |
923 | 935 |
924 default: | 936 default: |
925 NOTREACHED(); | 937 NOTREACHED(); |
926 } | 938 } |
927 } | 939 } |
928 | 940 |
| 941 bool HistoryService::AreEquivalentContexts(content::BrowserContext* context1, |
| 942 content::BrowserContext* context2) { |
| 943 DCHECK(context1); |
| 944 DCHECK(context2); |
| 945 |
| 946 Profile* profile1 = Profile::FromBrowserContext(context1); |
| 947 Profile* profile2 = Profile::FromBrowserContext(context2); |
| 948 |
| 949 return profile1->IsSameProfile(profile2); |
| 950 } |
| 951 |
| 952 void HistoryService::RebuildTable(URLEnumerator* enumerator) { |
| 953 DCHECK(thread_checker_.CalledOnValidThread()); |
| 954 ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::IterateURLs, enumerator); |
| 955 } |
| 956 |
929 bool HistoryService::Init(const FilePath& history_dir, | 957 bool HistoryService::Init(const FilePath& history_dir, |
930 BookmarkService* bookmark_service, | 958 BookmarkService* bookmark_service, |
931 bool no_db) { | 959 bool no_db) { |
932 DCHECK(thread_checker_.CalledOnValidThread()); | 960 DCHECK(thread_checker_.CalledOnValidThread()); |
933 if (!thread_->Start()) { | 961 if (!thread_->Start()) { |
934 Cleanup(); | 962 Cleanup(); |
935 return false; | 963 return false; |
936 } | 964 } |
937 | 965 |
938 history_dir_ = history_dir; | 966 history_dir_ = history_dir; |
939 bookmark_service_ = bookmark_service; | 967 bookmark_service_ = bookmark_service; |
940 no_db_ = no_db; | 968 no_db_ = no_db; |
941 | 969 |
942 if (profile_) { | 970 if (profile_) { |
943 std::string languages = | 971 std::string languages = |
944 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); | 972 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages); |
945 in_memory_url_index_.reset( | 973 in_memory_url_index_.reset( |
946 new history::InMemoryURLIndex(profile_, history_dir_, languages)); | 974 new history::InMemoryURLIndex(profile_, history_dir_, languages)); |
947 in_memory_url_index_->Init(); | 975 in_memory_url_index_->Init(); |
948 } | 976 } |
949 | 977 |
950 // Create the history backend. | 978 // Create the history backend. |
951 LoadBackendIfNecessary(); | 979 LoadBackendIfNecessary(); |
| 980 |
| 981 if (visitedlink_master_) { |
| 982 bool result = visitedlink_master_->Init(); |
| 983 DCHECK(result); |
| 984 } |
| 985 |
952 return true; | 986 return true; |
953 } | 987 } |
954 | 988 |
955 void HistoryService::ScheduleAutocomplete(HistoryURLProvider* provider, | 989 void HistoryService::ScheduleAutocomplete(HistoryURLProvider* provider, |
956 HistoryURLProviderParams* params) { | 990 HistoryURLProviderParams* params) { |
957 DCHECK(thread_checker_.CalledOnValidThread()); | 991 DCHECK(thread_checker_.CalledOnValidThread()); |
958 ScheduleAndForget(PRIORITY_UI, &HistoryBackend::ScheduleAutocomplete, | 992 ScheduleAndForget(PRIORITY_UI, &HistoryBackend::ScheduleAutocomplete, |
959 scoped_refptr<HistoryURLProvider>(provider), params); | 993 scoped_refptr<HistoryURLProvider>(provider), params); |
960 } | 994 } |
961 | 995 |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 } | 1365 } |
1332 } | 1366 } |
1333 | 1367 |
1334 void HistoryService::OnDeleteDirectiveProcessed( | 1368 void HistoryService::OnDeleteDirectiveProcessed( |
1335 const sync_pb::HistoryDeleteDirectiveSpecifics& delete_directive) { | 1369 const sync_pb::HistoryDeleteDirectiveSpecifics& delete_directive) { |
1336 DVLOG(1) << "Processed delete directive: " | 1370 DVLOG(1) << "Processed delete directive: " |
1337 << DeleteDirectiveToString(delete_directive); | 1371 << DeleteDirectiveToString(delete_directive); |
1338 // TODO(akalin): Keep track of which delete directives we've already | 1372 // TODO(akalin): Keep track of which delete directives we've already |
1339 // processed. | 1373 // processed. |
1340 } | 1374 } |
OLD | NEW |