Chromium Code Reviews| 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 |