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