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