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 #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 thumbnail_db_.reset(new ThumbnailDatabase()); | 622 thumbnail_db_.reset(new ThumbnailDatabase()); |
| 623 if (!db_->GetNeedsThumbnailMigration()) { | 623 if (!db_->GetNeedsThumbnailMigration()) { |
| 624 // No convertion needed - use new filename right away. | 624 // No convertion needed - use new filename right away. |
| 625 thumbnail_name = GetFaviconsFileName(); | 625 thumbnail_name = GetFaviconsFileName(); |
| 626 } | 626 } |
| 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 if (db_->GetNeedsThumbnailMigration()) { | 639 if (db_->GetNeedsThumbnailMigration()) { |
| 640 VLOG(1) << "Starting TopSites migration"; | 640 VLOG(1) << "Starting TopSites migration"; |
| 641 delegate_->StartTopSitesMigration(id_); | 641 delegate_->StartTopSitesMigration(id_); |
| 642 } | 642 } |
| (...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1890 favicon_sizes.erase(favicon_sizes.begin()); | 1890 favicon_sizes.erase(favicon_sizes.begin()); |
| 1891 } | 1891 } |
| 1892 thumbnail_db_->AddFaviconBitmap(favicon_id, bitmap_data, base::Time::Now(), | 1892 thumbnail_db_->AddFaviconBitmap(favicon_id, bitmap_data, base::Time::Now(), |
| 1893 pixel_size); | 1893 pixel_size); |
| 1894 favicon_sizes.push_back(pixel_size); | 1894 favicon_sizes.push_back(pixel_size); |
| 1895 } | 1895 } |
| 1896 | 1896 |
| 1897 // A site may have changed the favicons that it uses for |page_url|. | 1897 // A site may have changed the favicons that it uses for |page_url|. |
| 1898 // Example Scenario: | 1898 // Example Scenario: |
| 1899 // page_url = news.google.com | 1899 // page_url = news.google.com |
| 1900 // Intial State: www.google.com/favicon.ico 16x16, 32x32 | 1900 // Initial State: www.google.com/favicon.ico 16x16, 32x32 |
| 1901 // MergeFavicon(news.google.com, news.google.com/news_specific.ico, ..., | 1901 // MergeFavicon(news.google.com, news.google.com/news_specific.ico, ..., |
| 1902 // ..., 16x16) | 1902 // ..., 16x16) |
| 1903 // | 1903 // |
| 1904 // Difficulties: | 1904 // Difficulties: |
| 1905 // 1. Sync requires that a call to GetFaviconsForURL() returns the | 1905 // 1. Sync requires that a call to GetFaviconsForURL() returns the |
| 1906 // |bitmap_data| passed into MergeFavicon(). | 1906 // |bitmap_data| passed into MergeFavicon(). |
| 1907 // - It is invalid for the 16x16 bitmap for www.google.com/favicon.ico to | 1907 // - It is invalid for the 16x16 bitmap for www.google.com/favicon.ico to |
| 1908 // stay mapped to news.google.com because it would be unclear which 16x16 | 1908 // stay mapped to news.google.com because it would be unclear which 16x16 |
| 1909 // bitmap should be returned via GetFaviconsForURL(). | 1909 // bitmap should be returned via GetFaviconsForURL(). |
| 1910 // | 1910 // |
| 1911 // 2. www.google.com/favicon.ico may be mapped to more than just | 1911 // 2. www.google.com/favicon.ico may be mapped to more than just |
| 1912 // news.google.com (eg www.google.com). | 1912 // news.google.com (eg www.google.com). |
| 1913 // - The 16x16 bitmap cannot be deleted from www.google.com/favicon.ico | 1913 // - The 16x16 bitmap cannot be deleted from www.google.com/favicon.ico |
| 1914 // | 1914 // |
| 1915 // To resolve these problems, we copy all of the favicon bitmaps previously | 1915 // To resolve these problems, we copy all of the favicon bitmaps previously |
| 1916 // mapped to news.google.com (|page_url|) and add them to the favicon at | 1916 // mapped to news.google.com (|page_url|) and add them to the favicon at |
| 1917 // news.google.com/news_specific.ico (|icon_url|). The favicon sizes for | 1917 // news.google.com/news_specific.ico (|icon_url|). The favicon sizes for |
| 1918 // |icon_url| are set to default to indicate that |icon_url| has incomplete | 1918 // |icon_url| are set to default to indicate that |icon_url| has incomplete |
| 1919 // / incorrect data. | 1919 // / incorrect data. |
| 1920 // Difficlty 1: All but news.google.com/news_specific.ico are unmapped from | 1920 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from |
| 1921 // news.google.com | 1921 // news.google.com |
| 1922 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not | 1922 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not |
| 1923 // modified. | 1923 // modified. |
| 1924 | 1924 |
| 1925 std::vector<IconMapping> icon_mappings; | 1925 std::vector<IconMapping> icon_mappings; |
| 1926 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); | 1926 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); |
| 1927 | 1927 |
| 1928 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| | 1928 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| |
| 1929 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. | 1929 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. |
| 1930 for (size_t i = 0; i < icon_mappings.size(); ++i) { | 1930 for (size_t i = 0; i < icon_mappings.size(); ++i) { |
| (...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2824 } | 2824 } |
| 2825 | 2825 |
| 2826 // Clear thumbnail and favicon history. The favicons for the given URLs will | 2826 // Clear thumbnail and favicon history. The favicons for the given URLs will |
| 2827 // be kept. | 2827 // be kept. |
| 2828 if (!ClearAllThumbnailHistory(&kept_urls)) { | 2828 if (!ClearAllThumbnailHistory(&kept_urls)) { |
| 2829 LOG(ERROR) << "Thumbnail history could not be cleared"; | 2829 LOG(ERROR) << "Thumbnail history could not be cleared"; |
| 2830 // We continue in this error case. If the user wants to delete their | 2830 // We continue in this error case. If the user wants to delete their |
| 2831 // history, we should delete as much as we can. | 2831 // history, we should delete as much as we can. |
| 2832 } | 2832 } |
| 2833 | 2833 |
| 2834 // ClearAllMainHistory will change the IDs of the URLs in kept_urls. Therfore, | 2834 // ClearAllMainHistory will change the IDs of the URLs in kept_urls. |
| 2835 // we clear the list afterwards to make sure nobody uses this invalid data. | 2835 // Therefore, we clear the list afterwards to make sure nobody uses this |
|
sky
2013/08/20 21:21:45
Why the wrapping here?
etienneb
2013/08/21 03:14:39
Therfore -> Therefore
And, after the fix, the lin
| |
| 2836 // invalid data. | |
| 2836 if (!ClearAllMainHistory(kept_urls)) | 2837 if (!ClearAllMainHistory(kept_urls)) |
| 2837 LOG(ERROR) << "Main history could not be cleared"; | 2838 LOG(ERROR) << "Main history could not be cleared"; |
| 2838 kept_urls.clear(); | 2839 kept_urls.clear(); |
| 2839 | 2840 |
| 2840 // Delete archived history. | 2841 // Delete archived history. |
| 2841 if (archived_db_) { | 2842 if (archived_db_) { |
| 2842 // Close the database and delete the file. | 2843 // Close the database and delete the file. |
| 2843 archived_db_.reset(); | 2844 archived_db_.reset(); |
| 2844 base::FilePath archived_file_name = GetArchivedFileName(); | 2845 base::FilePath archived_file_name = GetArchivedFileName(); |
| 2845 sql::Connection::Delete(archived_file_name); | 2846 sql::Connection::Delete(archived_file_name); |
| 2846 | 2847 |
| 2847 // Now re-initialize the database (which may fail). | 2848 // Now re-initialize the database (which may fail). |
| 2848 archived_db_.reset(new ArchivedDatabase()); | 2849 archived_db_.reset(new ArchivedDatabase()); |
| 2849 if (!archived_db_->Init(archived_file_name)) { | 2850 if (!archived_db_->Init(archived_file_name)) { |
| 2850 LOG(WARNING) << "Could not initialize the archived database."; | 2851 LOG(WARNING) << "Could not initialize the archived database."; |
| 2851 archived_db_.reset(); | 2852 archived_db_.reset(); |
| 2852 } else { | 2853 } else { |
| 2853 // Open our long-running transaction on this database. | 2854 // Open our long-running transaction on this database. |
| 2854 archived_db_->BeginTransaction(); | 2855 archived_db_->BeginTransaction(); |
| 2855 } | 2856 } |
| 2856 } | 2857 } |
| 2857 | 2858 |
| 2858 db_->GetStartDate(&first_recorded_time_); | 2859 db_->GetStartDate(&first_recorded_time_); |
| 2859 | 2860 |
| 2860 // Send out the notfication that history is cleared. The in-memory datdabase | 2861 // Send out the notification that history is cleared. The in-memory database |
| 2861 // will pick this up and clear itself. | 2862 // will pick this up and clear itself. |
| 2862 URLsDeletedDetails* details = new URLsDeletedDetails; | 2863 URLsDeletedDetails* details = new URLsDeletedDetails; |
| 2863 details->all_history = true; | 2864 details->all_history = true; |
| 2864 NotifySyncURLsDeleted(true, false, NULL); | 2865 NotifySyncURLsDeleted(true, false, NULL); |
| 2865 BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_DELETED, details); | 2866 BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_DELETED, details); |
| 2866 } | 2867 } |
| 2867 | 2868 |
| 2868 bool HistoryBackend::ClearAllThumbnailHistory(URLRows* kept_urls) { | 2869 bool HistoryBackend::ClearAllThumbnailHistory(URLRows* kept_urls) { |
| 2869 if (!thumbnail_db_) { | 2870 if (!thumbnail_db_) { |
| 2870 // When we have no reference to the thumbnail database, maybe there was an | 2871 // When we have no reference to the thumbnail database, maybe there was an |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2898 FaviconMap::const_iterator found = copied_favicons.find(old_id); | 2899 FaviconMap::const_iterator found = copied_favicons.find(old_id); |
| 2899 if (found == copied_favicons.end()) { | 2900 if (found == copied_favicons.end()) { |
| 2900 new_id = thumbnail_db_->CopyFaviconAndFaviconBitmapsToTemporaryTables( | 2901 new_id = thumbnail_db_->CopyFaviconAndFaviconBitmapsToTemporaryTables( |
| 2901 old_id); | 2902 old_id); |
| 2902 copied_favicons[old_id] = new_id; | 2903 copied_favicons[old_id] = new_id; |
| 2903 } else { | 2904 } else { |
| 2904 // We already encountered a URL that used this favicon, use the ID we | 2905 // We already encountered a URL that used this favicon, use the ID we |
| 2905 // previously got. | 2906 // previously got. |
| 2906 new_id = found->second; | 2907 new_id = found->second; |
| 2907 } | 2908 } |
| 2908 // Add Icon mapping, and we don't care wheteher it suceeded or not. | 2909 // Add Icon mapping, and we don't care whether it succeeded or not. |
| 2909 thumbnail_db_->AddToTemporaryIconMappingTable(i->url(), new_id); | 2910 thumbnail_db_->AddToTemporaryIconMappingTable(i->url(), new_id); |
| 2910 } | 2911 } |
| 2911 } | 2912 } |
| 2912 #if defined(OS_ANDROID) | 2913 #if defined(OS_ANDROID) |
| 2913 // TODO (michaelbai): Add the unit test once AndroidProviderBackend is | 2914 // TODO (michaelbai): Add the unit test once AndroidProviderBackend is |
| 2914 // avaliable in HistoryBackend. | 2915 // avaliable in HistoryBackend. |
| 2915 db_->ClearAndroidURLRows(); | 2916 db_->ClearAndroidURLRows(); |
| 2916 #endif | 2917 #endif |
| 2917 | 2918 |
| 2918 // Drop original favicon_bitmaps, favicons, and icon mapping tables and | 2919 // Drop original favicon_bitmaps, favicons, and icon mapping tables and |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2930 thumbnail_db_->Vacuum(); | 2931 thumbnail_db_->Vacuum(); |
| 2931 thumbnail_db_->BeginTransaction(); | 2932 thumbnail_db_->BeginTransaction(); |
| 2932 return true; | 2933 return true; |
| 2933 } | 2934 } |
| 2934 | 2935 |
| 2935 bool HistoryBackend::ClearAllMainHistory(const URLRows& kept_urls) { | 2936 bool HistoryBackend::ClearAllMainHistory(const URLRows& kept_urls) { |
| 2936 // Create the duplicate URL table. We will copy the kept URLs into this. | 2937 // Create the duplicate URL table. We will copy the kept URLs into this. |
| 2937 if (!db_->CreateTemporaryURLTable()) | 2938 if (!db_->CreateTemporaryURLTable()) |
| 2938 return false; | 2939 return false; |
| 2939 | 2940 |
| 2940 // Insert the URLs into the temporary table, we need to keep a map of changed | 2941 // Insert the URLs into the temporary table. |
| 2941 // IDs since the ID will be different in the new table. | |
| 2942 typedef std::map<URLID, URLID> URLIDMap; | |
| 2943 URLIDMap old_to_new; // Maps original ID to new one. | |
| 2944 for (URLRows::const_iterator i = kept_urls.begin(); i != kept_urls.end(); | 2942 for (URLRows::const_iterator i = kept_urls.begin(); i != kept_urls.end(); |
| 2945 ++i) { | 2943 ++i) { |
| 2946 URLID new_id = db_->AddTemporaryURL(*i); | 2944 db_->AddTemporaryURL(*i); |
| 2947 old_to_new[i->id()] = new_id; | |
| 2948 } | 2945 } |
| 2949 | 2946 |
| 2950 // Replace the original URL table with the temporary one. | 2947 // Replace the original URL table with the temporary one. |
| 2951 if (!db_->CommitTemporaryURLTable()) | 2948 if (!db_->CommitTemporaryURLTable()) |
| 2952 return false; | 2949 return false; |
| 2953 | 2950 |
| 2954 // Delete the old tables and recreate them empty. | 2951 // Delete the old tables and recreate them empty. |
| 2955 db_->RecreateAllTablesButURL(); | 2952 db_->RecreateAllTablesButURL(); |
| 2956 | 2953 |
| 2957 // Vacuum to reclaim the space from the dropped tables. This must be done | 2954 // 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... | |
| 3000 int rank = kPageVisitStatsMaxTopSites; | 2997 int rank = kPageVisitStatsMaxTopSites; |
| 3001 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); | 2998 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); |
| 3002 if (it != most_visited_urls_map_.end()) | 2999 if (it != most_visited_urls_map_.end()) |
| 3003 rank = (*it).second; | 3000 rank = (*it).second; |
| 3004 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", | 3001 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", |
| 3005 rank, kPageVisitStatsMaxTopSites + 1); | 3002 rank, kPageVisitStatsMaxTopSites + 1); |
| 3006 } | 3003 } |
| 3007 #endif | 3004 #endif |
| 3008 | 3005 |
| 3009 } // namespace history | 3006 } // namespace history |
| OLD | NEW |