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 #include "chrome/browser/history/history_backend.h" | 5 #include "chrome/browser/history/history_backend.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <list> | 9 #include <list> |
10 #include <map> | 10 #include <map> |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 | 300 |
301 // Are we at the beginning of a new segment? | 301 // Are we at the beginning of a new segment? |
302 // Note that navigating to an existing entry (with back/forward) reuses the | 302 // Note that navigating to an existing entry (with back/forward) reuses the |
303 // same transition type. We are not adding it as a new segment in that case | 303 // same transition type. We are not adding it as a new segment in that case |
304 // because if this was the target of a redirect, we might end up with | 304 // because if this was the target of a redirect, we might end up with |
305 // 2 entries for the same final URL. Ex: User types google.net, gets | 305 // 2 entries for the same final URL. Ex: User types google.net, gets |
306 // redirected to google.com. A segment is created for google.net. On | 306 // redirected to google.com. A segment is created for google.net. On |
307 // google.com users navigates through a link, then press back. That last | 307 // google.com users navigates through a link, then press back. That last |
308 // navigation is for the entry google.com transition typed. We end up adding | 308 // navigation is for the entry google.com transition typed. We end up adding |
309 // a segment for that one as well. So we end up with google.net and google.com | 309 // a segment for that one as well. So we end up with google.net and google.com |
310 // in the segement table, showing as 2 entries in the NTP. | 310 // in the segment table, showing as 2 entries in the NTP. |
311 // Note also that we should still be updating the visit count for that segment | 311 // Note also that we should still be updating the visit count for that segment |
312 // which we are not doing now. It should be addressed when | 312 // which we are not doing now. It should be addressed when |
313 // http://crbug.com/96860 is fixed. | 313 // http://crbug.com/96860 is fixed. |
314 if ((t == content::PAGE_TRANSITION_TYPED || | 314 if ((t == content::PAGE_TRANSITION_TYPED || |
315 t == content::PAGE_TRANSITION_AUTO_BOOKMARK) && | 315 t == content::PAGE_TRANSITION_AUTO_BOOKMARK) && |
316 (transition_type & content::PAGE_TRANSITION_FORWARD_BACK) == 0) { | 316 (transition_type & content::PAGE_TRANSITION_FORWARD_BACK) == 0) { |
317 // If so, create or get the segment. | 317 // If so, create or get the segment. |
318 std::string segment_name = db_->ComputeSegmentName(url); | 318 std::string segment_name = db_->ComputeSegmentName(url); |
319 URLID url_id = db_->GetRowForURL(url, NULL); | 319 URLID url_id = db_->GetRowForURL(url, NULL); |
320 if (!url_id) | 320 if (!url_id) |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 // TODO(shess): "thumbnail database" these days only stores | 622 // TODO(shess): "thumbnail database" these days only stores |
623 // favicons. Thumbnails are stored in "top sites". Consider | 623 // favicons. Thumbnails are stored in "top sites". Consider |
624 // renaming "thumbnail" references to "favicons" or something of the | 624 // renaming "thumbnail" references to "favicons" or something of the |
625 // sort. | 625 // sort. |
626 thumbnail_db_.reset(new ThumbnailDatabase()); | 626 thumbnail_db_.reset(new ThumbnailDatabase()); |
627 if (thumbnail_db_->Init(thumbnail_name, | 627 if (thumbnail_db_->Init(thumbnail_name, |
628 history_publisher_.get(), | 628 history_publisher_.get(), |
629 db_.get()) != sql::INIT_OK) { | 629 db_.get()) != sql::INIT_OK) { |
630 // Unlike the main database, we don't error out when the database is too | 630 // Unlike the main database, we don't error out when the database is too |
631 // new because this error is much less severe. Generally, this shouldn't | 631 // new because this error is much less severe. Generally, this shouldn't |
632 // happen since the thumbnail and main datbase versions should be in sync. | 632 // happen since the thumbnail and main database versions should be in sync. |
633 // We'll just continue without thumbnails & favicons in this case or any | 633 // We'll just continue without thumbnails & favicons in this case or any |
634 // other error. | 634 // other error. |
635 LOG(WARNING) << "Could not initialize the thumbnail database."; | 635 LOG(WARNING) << "Could not initialize the thumbnail database."; |
636 thumbnail_db_.reset(); | 636 thumbnail_db_.reset(); |
637 } | 637 } |
638 | 638 |
639 // Archived database. | 639 // Archived database. |
640 if (db_->needs_version_17_migration()) { | 640 if (db_->needs_version_17_migration()) { |
641 // See needs_version_17_migration() decl for more. In this case, we want | 641 // See needs_version_17_migration() decl for more. In this case, we want |
642 // to delete the archived database and need to do so before we try to | 642 // to delete the archived database and need to do so before we try to |
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1771 favicon_sizes.erase(favicon_sizes.begin()); | 1771 favicon_sizes.erase(favicon_sizes.begin()); |
1772 } | 1772 } |
1773 thumbnail_db_->AddFaviconBitmap(favicon_id, bitmap_data, base::Time::Now(), | 1773 thumbnail_db_->AddFaviconBitmap(favicon_id, bitmap_data, base::Time::Now(), |
1774 pixel_size); | 1774 pixel_size); |
1775 favicon_sizes.push_back(pixel_size); | 1775 favicon_sizes.push_back(pixel_size); |
1776 } | 1776 } |
1777 | 1777 |
1778 // A site may have changed the favicons that it uses for |page_url|. | 1778 // A site may have changed the favicons that it uses for |page_url|. |
1779 // Example Scenario: | 1779 // Example Scenario: |
1780 // page_url = news.google.com | 1780 // page_url = news.google.com |
1781 // Intial State: www.google.com/favicon.ico 16x16, 32x32 | 1781 // Initial State: www.google.com/favicon.ico 16x16, 32x32 |
1782 // MergeFavicon(news.google.com, news.google.com/news_specific.ico, ..., | 1782 // MergeFavicon(news.google.com, news.google.com/news_specific.ico, ..., |
1783 // ..., 16x16) | 1783 // ..., 16x16) |
1784 // | 1784 // |
1785 // Difficulties: | 1785 // Difficulties: |
1786 // 1. Sync requires that a call to GetFaviconsForURL() returns the | 1786 // 1. Sync requires that a call to GetFaviconsForURL() returns the |
1787 // |bitmap_data| passed into MergeFavicon(). | 1787 // |bitmap_data| passed into MergeFavicon(). |
1788 // - It is invalid for the 16x16 bitmap for www.google.com/favicon.ico to | 1788 // - It is invalid for the 16x16 bitmap for www.google.com/favicon.ico to |
1789 // stay mapped to news.google.com because it would be unclear which 16x16 | 1789 // stay mapped to news.google.com because it would be unclear which 16x16 |
1790 // bitmap should be returned via GetFaviconsForURL(). | 1790 // bitmap should be returned via GetFaviconsForURL(). |
1791 // | 1791 // |
1792 // 2. www.google.com/favicon.ico may be mapped to more than just | 1792 // 2. www.google.com/favicon.ico may be mapped to more than just |
1793 // news.google.com (eg www.google.com). | 1793 // news.google.com (eg www.google.com). |
1794 // - The 16x16 bitmap cannot be deleted from www.google.com/favicon.ico | 1794 // - The 16x16 bitmap cannot be deleted from www.google.com/favicon.ico |
1795 // | 1795 // |
1796 // To resolve these problems, we copy all of the favicon bitmaps previously | 1796 // To resolve these problems, we copy all of the favicon bitmaps previously |
1797 // mapped to news.google.com (|page_url|) and add them to the favicon at | 1797 // mapped to news.google.com (|page_url|) and add them to the favicon at |
1798 // news.google.com/news_specific.ico (|icon_url|). The favicon sizes for | 1798 // news.google.com/news_specific.ico (|icon_url|). The favicon sizes for |
1799 // |icon_url| are set to default to indicate that |icon_url| has incomplete | 1799 // |icon_url| are set to default to indicate that |icon_url| has incomplete |
1800 // / incorrect data. | 1800 // / incorrect data. |
1801 // Difficlty 1: All but news.google.com/news_specific.ico are unmapped from | 1801 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from |
1802 // news.google.com | 1802 // news.google.com |
1803 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not | 1803 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not |
1804 // modified. | 1804 // modified. |
1805 | 1805 |
1806 std::vector<IconMapping> icon_mappings; | 1806 std::vector<IconMapping> icon_mappings; |
1807 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); | 1807 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); |
1808 | 1808 |
1809 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| | 1809 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| |
1810 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. | 1810 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. |
1811 for (size_t i = 0; i < icon_mappings.size(); ++i) { | 1811 for (size_t i = 0; i < icon_mappings.size(); ++i) { |
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2705 } | 2705 } |
2706 | 2706 |
2707 // Clear thumbnail and favicon history. The favicons for the given URLs will | 2707 // Clear thumbnail and favicon history. The favicons for the given URLs will |
2708 // be kept. | 2708 // be kept. |
2709 if (!ClearAllThumbnailHistory(kept_urls)) { | 2709 if (!ClearAllThumbnailHistory(kept_urls)) { |
2710 LOG(ERROR) << "Thumbnail history could not be cleared"; | 2710 LOG(ERROR) << "Thumbnail history could not be cleared"; |
2711 // We continue in this error case. If the user wants to delete their | 2711 // We continue in this error case. If the user wants to delete their |
2712 // history, we should delete as much as we can. | 2712 // history, we should delete as much as we can. |
2713 } | 2713 } |
2714 | 2714 |
2715 // ClearAllMainHistory will change the IDs of the URLs in kept_urls. Therfore, | 2715 // ClearAllMainHistory will change the IDs of the URLs in kept_urls. |
2716 // we clear the list afterwards to make sure nobody uses this invalid data. | 2716 // Therefore, we clear the list afterwards to make sure nobody uses this |
| 2717 // invalid data. |
2717 if (!ClearAllMainHistory(kept_urls)) | 2718 if (!ClearAllMainHistory(kept_urls)) |
2718 LOG(ERROR) << "Main history could not be cleared"; | 2719 LOG(ERROR) << "Main history could not be cleared"; |
2719 kept_urls.clear(); | 2720 kept_urls.clear(); |
2720 | 2721 |
2721 // Delete archived history. | 2722 // Delete archived history. |
2722 if (archived_db_) { | 2723 if (archived_db_) { |
2723 // Close the database and delete the file. | 2724 // Close the database and delete the file. |
2724 archived_db_.reset(); | 2725 archived_db_.reset(); |
2725 base::FilePath archived_file_name = GetArchivedFileName(); | 2726 base::FilePath archived_file_name = GetArchivedFileName(); |
2726 sql::Connection::Delete(archived_file_name); | 2727 sql::Connection::Delete(archived_file_name); |
2727 | 2728 |
2728 // Now re-initialize the database (which may fail). | 2729 // Now re-initialize the database (which may fail). |
2729 archived_db_.reset(new ArchivedDatabase()); | 2730 archived_db_.reset(new ArchivedDatabase()); |
2730 if (!archived_db_->Init(archived_file_name)) { | 2731 if (!archived_db_->Init(archived_file_name)) { |
2731 LOG(WARNING) << "Could not initialize the archived database."; | 2732 LOG(WARNING) << "Could not initialize the archived database."; |
2732 archived_db_.reset(); | 2733 archived_db_.reset(); |
2733 } else { | 2734 } else { |
2734 // Open our long-running transaction on this database. | 2735 // Open our long-running transaction on this database. |
2735 archived_db_->BeginTransaction(); | 2736 archived_db_->BeginTransaction(); |
2736 } | 2737 } |
2737 } | 2738 } |
2738 | 2739 |
2739 db_->GetStartDate(&first_recorded_time_); | 2740 db_->GetStartDate(&first_recorded_time_); |
2740 | 2741 |
2741 // Send out the notfication that history is cleared. The in-memory datdabase | 2742 // Send out the notification that history is cleared. The in-memory database |
2742 // will pick this up and clear itself. | 2743 // will pick this up and clear itself. |
2743 URLsDeletedDetails* details = new URLsDeletedDetails; | 2744 URLsDeletedDetails* details = new URLsDeletedDetails; |
2744 details->all_history = true; | 2745 details->all_history = true; |
2745 NotifySyncURLsDeleted(true, false, NULL); | 2746 NotifySyncURLsDeleted(true, false, NULL); |
2746 BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_DELETED, details); | 2747 BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_DELETED, details); |
2747 } | 2748 } |
2748 | 2749 |
2749 bool HistoryBackend::ClearAllThumbnailHistory(const URLRows& kept_urls) { | 2750 bool HistoryBackend::ClearAllThumbnailHistory(const URLRows& kept_urls) { |
2750 if (!thumbnail_db_) { | 2751 if (!thumbnail_db_) { |
2751 // When we have no reference to the thumbnail database, maybe there was an | 2752 // When we have no reference to the thumbnail database, maybe there was an |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2792 thumbnail_db_->Vacuum(); | 2793 thumbnail_db_->Vacuum(); |
2793 thumbnail_db_->BeginTransaction(); | 2794 thumbnail_db_->BeginTransaction(); |
2794 return true; | 2795 return true; |
2795 } | 2796 } |
2796 | 2797 |
2797 bool HistoryBackend::ClearAllMainHistory(const URLRows& kept_urls) { | 2798 bool HistoryBackend::ClearAllMainHistory(const URLRows& kept_urls) { |
2798 // Create the duplicate URL table. We will copy the kept URLs into this. | 2799 // Create the duplicate URL table. We will copy the kept URLs into this. |
2799 if (!db_->CreateTemporaryURLTable()) | 2800 if (!db_->CreateTemporaryURLTable()) |
2800 return false; | 2801 return false; |
2801 | 2802 |
2802 // Insert the URLs into the temporary table, we need to keep a map of changed | 2803 // Insert the URLs into the temporary table. |
2803 // IDs since the ID will be different in the new table. | |
2804 typedef std::map<URLID, URLID> URLIDMap; | |
2805 URLIDMap old_to_new; // Maps original ID to new one. | |
2806 for (URLRows::const_iterator i = kept_urls.begin(); i != kept_urls.end(); | 2804 for (URLRows::const_iterator i = kept_urls.begin(); i != kept_urls.end(); |
2807 ++i) { | 2805 ++i) { |
2808 URLID new_id = db_->AddTemporaryURL(*i); | 2806 db_->AddTemporaryURL(*i); |
2809 old_to_new[i->id()] = new_id; | |
2810 } | 2807 } |
2811 | 2808 |
2812 // Replace the original URL table with the temporary one. | 2809 // Replace the original URL table with the temporary one. |
2813 if (!db_->CommitTemporaryURLTable()) | 2810 if (!db_->CommitTemporaryURLTable()) |
2814 return false; | 2811 return false; |
2815 | 2812 |
2816 // Delete the old tables and recreate them empty. | 2813 // Delete the old tables and recreate them empty. |
2817 db_->RecreateAllTablesButURL(); | 2814 db_->RecreateAllTablesButURL(); |
2818 | 2815 |
2819 // Vacuum to reclaim the space from the dropped tables. This must be done | 2816 // Vacuum to reclaim the space from the dropped tables. This must be done |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2862 int rank = kPageVisitStatsMaxTopSites; | 2859 int rank = kPageVisitStatsMaxTopSites; |
2863 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); | 2860 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); |
2864 if (it != most_visited_urls_map_.end()) | 2861 if (it != most_visited_urls_map_.end()) |
2865 rank = (*it).second; | 2862 rank = (*it).second; |
2866 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", | 2863 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", |
2867 rank, kPageVisitStatsMaxTopSites + 1); | 2864 rank, kPageVisitStatsMaxTopSites + 1); |
2868 } | 2865 } |
2869 #endif | 2866 #endif |
2870 | 2867 |
2871 } // namespace history | 2868 } // namespace history |
OLD | NEW |