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