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