| 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 |