Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(851)

Side by Side Diff: chrome/browser/history/history_backend.cc

Issue 10802066: Adds support for saving favicon size into history database. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <list> 7 #include <list>
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/file_util.h" 14 #include "base/file_util.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/scoped_vector.h" 16 #include "base/memory/scoped_vector.h"
17 #include "base/message_loop.h" 17 #include "base/message_loop.h"
18 #include "base/metrics/histogram.h" 18 #include "base/metrics/histogram.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/time.h" 20 #include "base/time.h"
21 #include "base/utf_string_conversions.h" 21 #include "base/utf_string_conversions.h"
22 #include "chrome/browser/autocomplete/history_url_provider.h" 22 #include "chrome/browser/autocomplete/history_url_provider.h"
23 #include "chrome/browser/bookmarks/bookmark_service.h" 23 #include "chrome/browser/bookmarks/bookmark_service.h"
24 #include "chrome/browser/cancelable_request.h" 24 #include "chrome/browser/cancelable_request.h"
25 #include "chrome/browser/favicon/select_favicon_frames.h"
25 #include "chrome/browser/history/history_notifications.h" 26 #include "chrome/browser/history/history_notifications.h"
26 #include "chrome/browser/history/history_publisher.h" 27 #include "chrome/browser/history/history_publisher.h"
27 #include "chrome/browser/history/in_memory_history_backend.h" 28 #include "chrome/browser/history/in_memory_history_backend.h"
28 #include "chrome/browser/history/page_usage_data.h" 29 #include "chrome/browser/history/page_usage_data.h"
29 #include "chrome/browser/history/top_sites.h" 30 #include "chrome/browser/history/top_sites.h"
30 #include "chrome/browser/history/visit_filter.h" 31 #include "chrome/browser/history/visit_filter.h"
31 #include "chrome/common/chrome_constants.h" 32 #include "chrome/common/chrome_constants.h"
32 #include "chrome/common/chrome_notification_types.h" 33 #include "chrome/common/chrome_notification_types.h"
33 #include "chrome/common/url_constants.h" 34 #include "chrome/common/url_constants.h"
34 #include "content/public/browser/download_persistent_store_info.h" 35 #include "content/public/browser/download_persistent_store_info.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 static const int kSessionCloseTimeWindowSecs = 10; 88 static const int kSessionCloseTimeWindowSecs = 10;
88 89
89 // The maximum number of items we'll allow in the redirect list before 90 // The maximum number of items we'll allow in the redirect list before
90 // deleting some. 91 // deleting some.
91 static const int kMaxRedirectCount = 32; 92 static const int kMaxRedirectCount = 32;
92 93
93 // The number of days old a history entry can be before it is considered "old" 94 // The number of days old a history entry can be before it is considered "old"
94 // and is archived. 95 // and is archived.
95 static const int kArchiveDaysThreshold = 90; 96 static const int kArchiveDaysThreshold = 90;
96 97
98 // The maximum number of icons URLs per page which can be stored in the
99 // thumbnail database.
100 const size_t kMaxFaviconsPerPage = 8;
101
102 // The maximum number of bitmaps for a single icon URL which can be stored in
103 // the thumbnail database.
104 const size_t kMaxFaviconBitmapsPerIconURL = 8;
105
97 // Converts from PageUsageData to MostVisitedURL. |redirects| is a 106 // Converts from PageUsageData to MostVisitedURL. |redirects| is a
98 // list of redirects for this URL. Empty list means no redirects. 107 // list of redirects for this URL. Empty list means no redirects.
99 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, 108 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data,
100 const RedirectList& redirects) { 109 const RedirectList& redirects) {
101 MostVisitedURL mv; 110 MostVisitedURL mv;
102 mv.url = page_data.GetURL(); 111 mv.url = page_data.GetURL();
103 mv.title = page_data.GetTitle(); 112 mv.title = page_data.GetTitle();
104 if (redirects.empty()) { 113 if (redirects.empty()) {
105 // Redirects must contain at least the target url. 114 // Redirects must contain at least the target url.
106 mv.redirects.push_back(mv.url); 115 mv.redirects.push_back(mv.url);
(...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 URLID url_id; 1773 URLID url_id;
1765 if ((url_id = db_->GetRowForURL(redirects.back(), NULL))) 1774 if ((url_id = db_->GetRowForURL(redirects.back(), NULL)))
1766 success = thumbnail_db_->GetPageThumbnail(url_id, data); 1775 success = thumbnail_db_->GetPageThumbnail(url_id, data);
1767 } 1776 }
1768 } 1777 }
1769 } 1778 }
1770 1779
1771 return success; 1780 return success;
1772 } 1781 }
1773 1782
1774 void HistoryBackend::GetFavicon(scoped_refptr<GetFaviconRequest> request, 1783 void HistoryBackend::GetFavicon(
1775 const GURL& icon_url, 1784 scoped_refptr<GetFaviconRequest> request,
1776 int icon_types) { 1785 const std::vector<GURL>& icon_urls,
1777 UpdateFaviconMappingAndFetchImpl(NULL, icon_url, request, icon_types); 1786 int icon_types,
1787 const gfx::Size& desired_dip_size,
1788 const std::vector<ui::ScaleFactor>& desired_scale_factors) {
1789 UpdateFaviconMappingsAndFetchImpl(NULL, icon_urls, request, icon_types,
1790 desired_dip_size, desired_scale_factors);
1778 } 1791 }
1779 1792
1780 void HistoryBackend::UpdateFaviconMappingAndFetch( 1793 void HistoryBackend::GetFaviconForURL(
1781 scoped_refptr<GetFaviconRequest> request, 1794 scoped_refptr<GetFaviconRequest> request,
1782 const GURL& page_url, 1795 const GURL& page_url,
1783 const GURL& icon_url, 1796 int icon_types,
1784 IconType icon_type) { 1797 const gfx::Size& desired_dip_size,
1785 UpdateFaviconMappingAndFetchImpl(&page_url, icon_url, request, icon_type); 1798 const std::vector<ui::ScaleFactor>& desired_scale_factors) {
1799 if (request->canceled())
1800 return;
1801
1802 FaviconData favicon_data;
1803 std::vector<GURL> mapped_icon_urls;
1804
1805 // Get the favicons from DB.
1806 GetFaviconFromDB(page_url, icon_types, desired_dip_size,
1807 desired_scale_factors, &favicon_data, &mapped_icon_urls);
1808
1809 request->ForwardResult(request->handle(), favicon_data, mapped_icon_urls);
1786 } 1810 }
1787 1811
1788 void HistoryBackend::SetFaviconOutOfDateForPage(const GURL& page_url) { 1812 void HistoryBackend::UpdateFaviconMappingsAndFetch(
1813 scoped_refptr<GetFaviconRequest> request,
1814 const GURL& page_url,
1815 const std::vector<GURL>& icon_urls,
1816 IconType icon_type,
1817 const gfx::Size& desired_dip_size,
1818 const std::vector<ui::ScaleFactor>& desired_scale_factors) {
1819 UpdateFaviconMappingsAndFetchImpl(&page_url, icon_urls, request, icon_type,
1820 desired_dip_size, desired_scale_factors);
1821 }
1822
1823 void HistoryBackend::AddFavicons(
1824 const GURL& page_url,
1825 const GURL& icon_url,
1826 IconType icon_type,
1827 const std::vector<FaviconBitmapData>& favicon_bitmaps) {
1828 /*FaviconData favicon_data;
1829 GetFaviconsFromDB(page_url, icon_type, &favicon_data);
1830
1831 IconURLSizesMap icon_url_sizes;
1832 if (favicon_data.known_icon) {
1833 icon_url_sizes = favicon_data.icon_url_sizes;
1834 } else {
1835 // The thumbnail database doesn't know about |page_url|. Guess at what
1836 // |icon_url_sizes| should be.
1837 for (size_t i = 0; i < elements.size(); ++i) {
1838 const GURL& icon_url = elements[i].icon_url;
1839 icon_url_sizes[icon_url].InsertSize(elements[i].pixel_size);
1840 }
1841 }
1842
1843 SetFavicons(page_url, icon_type, elements, icon_url_sizes);
1844 */
1845 }
1846
1847 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) {
1789 std::vector<IconMapping> icon_mappings; 1848 std::vector<IconMapping> icon_mappings;
1790 1849
1791 if (!thumbnail_db_.get() || 1850 if (!thumbnail_db_.get() ||
1792 !thumbnail_db_->GetIconMappingsForPageURL(page_url, 1851 !thumbnail_db_->GetIconMappingsForPageURL(page_url,
1793 &icon_mappings)) 1852 &icon_mappings))
1794 return; 1853 return;
1795 1854
1796 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); 1855 for (std::vector<IconMapping>::iterator m = icon_mappings.begin();
1797 m != icon_mappings.end(); ++m) { 1856 m != icon_mappings.end(); ++m) {
1798 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); 1857 thumbnail_db_->SetFaviconOutOfDate(m->icon_id);
1799 } 1858 }
1800 ScheduleCommit(); 1859 ScheduleCommit();
1801 } 1860 }
1802 1861
1803 void HistoryBackend::CloneFavicon(const GURL& old_page_url, 1862 void HistoryBackend::CloneFavicons(const GURL& old_page_url,
1804 const GURL& new_page_url) { 1863 const GURL& new_page_url) {
1805 if (!thumbnail_db_.get()) 1864 if (!thumbnail_db_.get())
1806 return; 1865 return;
1807 1866
1808 // Prevent cross-domain cloning. 1867 // Prevent cross-domain cloning.
1809 if (old_page_url.GetOrigin() != new_page_url.GetOrigin()) 1868 if (old_page_url.GetOrigin() != new_page_url.GetOrigin())
1810 return; 1869 return;
1811 1870
1812 thumbnail_db_->CloneIconMapping(old_page_url, new_page_url); 1871 thumbnail_db_->CloneIconMappings(old_page_url, new_page_url);
1813 ScheduleCommit(); 1872 ScheduleCommit();
1814 } 1873 }
1815 1874
1816 void HistoryBackend::SetImportedFavicons( 1875 void HistoryBackend::SetImportedFavicons(
1817 const std::vector<ImportedFaviconUsage>& favicon_usage) { 1876 const std::vector<ImportedFaviconUsage>& favicon_usage) {
1818 if (!db_.get() || !thumbnail_db_.get()) 1877 if (!db_.get() || !thumbnail_db_.get())
1819 return; 1878 return;
1820 1879
1821 Time now = Time::Now(); 1880 Time now = Time::Now();
1822 1881
1823 // Track all URLs that had their favicons set or updated. 1882 // Track all URLs that had their favicons set or updated.
1824 std::set<GURL> favicons_changed; 1883 std::set<GURL> favicons_changed;
1825 1884
1826 for (size_t i = 0; i < favicon_usage.size(); i++) { 1885 for (size_t i = 0; i < favicon_usage.size(); i++) {
1827 FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL( 1886 FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL(
1828 favicon_usage[i].favicon_url, history::FAVICON, NULL); 1887 favicon_usage[i].favicon_url, history::FAVICON);
1829 if (!favicon_id) { 1888 if (!favicon_id) {
1830 // This favicon doesn't exist yet, so we create it using the given data. 1889 // This favicon doesn't exist yet, so we create it using the given data.
1831 // TODO(pkotwicz): Pass in real pixel size. 1890 // TODO(pkotwicz): Pass in real pixel size.
1832 favicon_id = thumbnail_db_->AddFavicon( 1891 favicon_id = thumbnail_db_->AddFavicon(
1833 favicon_usage[i].favicon_url, 1892 favicon_usage[i].favicon_url,
1834 history::FAVICON, 1893 history::FAVICON,
1835 std::string("0 0"), 1894 kDefaultFaviconSizes,
1836 new base::RefCountedBytes(favicon_usage[i].png_data), 1895 new base::RefCountedBytes(favicon_usage[i].png_data),
1837 now, 1896 now,
1838 gfx::Size()); 1897 gfx::Size());
1839 } 1898 }
1840 1899
1841 // Save the mapping from all the URLs to the favicon. 1900 // Save the mapping from all the URLs to the favicon.
1842 BookmarkService* bookmark_service = GetBookmarkService(); 1901 BookmarkService* bookmark_service = GetBookmarkService();
1843 for (std::set<GURL>::const_iterator url = favicon_usage[i].urls.begin(); 1902 for (std::set<GURL>::const_iterator url = favicon_usage[i].urls.begin();
1844 url != favicon_usage[i].urls.end(); ++url) { 1903 url != favicon_usage[i].urls.end(); ++url) {
1845 URLRow url_row; 1904 URLRow url_row;
1846 if (!db_->GetRowForURL(*url, &url_row)) { 1905 if (!db_->GetRowForURL(*url, &url_row)) {
1847 // If the URL is present as a bookmark, add the url in history to 1906 // If the URL is present as a bookmark, add the url in history to
1848 // save the favicon mapping. This will match with what history db does 1907 // save the favicon mapping. This will match with what history db does
1849 // for regular bookmarked URLs with favicons - when history db is 1908 // for regular bookmarked URLs with favicons - when history db is
1850 // cleaned, we keep an entry in the db with 0 visits as long as that 1909 // cleaned, we keep an entry in the db with 0 visits as long as that
1851 // url is bookmarked. 1910 // url is bookmarked.
1852 if (bookmark_service && bookmark_service_->IsBookmarked(*url)) { 1911 if (bookmark_service && bookmark_service_->IsBookmarked(*url)) {
1853 URLRow url_info(*url); 1912 URLRow url_info(*url);
1854 url_info.set_visit_count(0); 1913 url_info.set_visit_count(0);
1855 url_info.set_typed_count(0); 1914 url_info.set_typed_count(0);
1856 url_info.set_last_visit(base::Time()); 1915 url_info.set_last_visit(base::Time());
1857 url_info.set_hidden(false); 1916 url_info.set_hidden(false);
1858 db_->AddURL(url_info); 1917 db_->AddURL(url_info);
1859 thumbnail_db_->AddIconMapping(*url, favicon_id); 1918 thumbnail_db_->AddIconMapping(*url, favicon_id);
1860 favicons_changed.insert(*url); 1919 favicons_changed.insert(*url);
1861 } 1920 }
1862 } else { 1921 } else {
1863 if (!thumbnail_db_->GetIconMappingForPageURL(*url, FAVICON, NULL)) { 1922 std::vector<IconMapping> icon_mappings_unused;
1923 if (!thumbnail_db_->GetIconMappingsForPageURL(*url, FAVICON,
1924 &icon_mappings_unused)) {
1864 // URL is present in history, update the favicon *only* if it is not 1925 // URL is present in history, update the favicon *only* if it is not
1865 // set already. 1926 // set already.
1866 thumbnail_db_->AddIconMapping(*url, favicon_id); 1927 thumbnail_db_->AddIconMapping(*url, favicon_id);
1867 favicons_changed.insert(*url); 1928 favicons_changed.insert(*url);
1868 } 1929 }
1869 } 1930 }
1870 } 1931 }
1871 } 1932 }
1872 1933
1873 if (!favicons_changed.empty()) { 1934 if (!favicons_changed.empty()) {
1874 // Send the notification about the changed favicon URLs. 1935 // Send the notification about the changed favicon URLs.
1875 FaviconChangeDetails* changed_details = new FaviconChangeDetails; 1936 FaviconChangeDetails* changed_details = new FaviconChangeDetails;
1876 changed_details->urls.swap(favicons_changed); 1937 changed_details->urls.swap(favicons_changed);
1877 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, 1938 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED,
1878 changed_details); 1939 changed_details);
1879 } 1940 }
1880 } 1941 }
1881 1942
1882 void HistoryBackend::UpdateFaviconMappingAndFetchImpl( 1943 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl(
1883 const GURL* page_url, 1944 const GURL* page_url,
1884 const GURL& icon_url, 1945 const std::vector<GURL>& icon_urls,
1885 scoped_refptr<GetFaviconRequest> request, 1946 scoped_refptr<GetFaviconRequest> request,
1886 int icon_types) { 1947 int icon_types,
1948 const gfx::Size& desired_dip_size,
1949 const std::vector<ui::ScaleFactor> desired_scale_factors) {
1887 // Check only a single type was given when the page_url was specified. 1950 // Check only a single type was given when the page_url was specified.
1888 DCHECK(!page_url || (page_url && (icon_types == FAVICON || 1951 DCHECK(!page_url || (page_url && (icon_types == FAVICON ||
1889 icon_types == TOUCH_ICON || icon_types == TOUCH_PRECOMPOSED_ICON))); 1952 icon_types == TOUCH_ICON || icon_types == TOUCH_PRECOMPOSED_ICON)));
1890 1953
1891 if (request->canceled()) 1954 if (request->canceled())
1892 return; 1955 return;
1893 1956
1894 FaviconData favicon_data; 1957 FaviconData favicon_data;
1895 1958 std::vector<GURL> icon_urls_in_db;
1959 IconURLFaviconIDMap icon_url_id_map;
1896 if (thumbnail_db_.get()) { 1960 if (thumbnail_db_.get()) {
1897 IconType icon_type; 1961 std::vector<FaviconID> favicon_ids;
1898 const FaviconID favicon_id = 1962 for (size_t i = 0; i < icon_urls.size(); ++i) {
1899 thumbnail_db_->GetFaviconIDForFaviconURL( 1963 const GURL& icon_url = icon_urls[i];
1900 icon_url, icon_types, &icon_type); 1964 const FaviconID favicon_id =
1901 if (favicon_id) { 1965 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_types);
1902 GetFaviconFromDB(favicon_id, &favicon_data); 1966 if (favicon_id) {
1903 1967 favicon_ids.push_back(favicon_id);
1904 if (page_url) 1968 icon_urls_in_db.push_back(icon_url);
1905 SetFaviconMapping(*page_url, favicon_id, icon_type); 1969 icon_url_id_map[icon_url] = favicon_id;
1906 } 1970 }
1907 // else case, haven't cached entry yet. Caller is responsible for 1971 // else case, haven't cached entry yet. Caller is responsible for
1908 // downloading the favicon and invoking SetFavicon. 1972 // downloading the favicon and invoking SetFavicons.
1909 } 1973 }
1910 // TODO(pkotwicz): Pass in icon_url if it exists in database instead of empty 1974 GetFaviconDataForBestMatch(favicon_ids, desired_dip_size,
1911 // vector. 1975 desired_scale_factors, &favicon_data);
1912 request->ForwardResult(request->handle(), favicon_data, std::vector<GURL>()); 1976 }
1913 } 1977
1914 1978 if (page_url) {
1915 void HistoryBackend::GetFaviconForURL( 1979 SetFaviconMappingsForPageAndRedirects(
1916 scoped_refptr<GetFaviconRequest> request, 1980 *page_url, favicon_data.icon_type, icon_url_id_map);
1917 const GURL& page_url, 1981 }
1918 int icon_types) { 1982 request->ForwardResult(request->handle(), favicon_data, icon_urls_in_db);
1919 if (request->canceled()) 1983 }
1920 return; 1984
1921 1985 void HistoryBackend::SetFavicons(
1922 FaviconData favicon_data;
1923
1924 // Get the favicon from DB.
1925 GetFaviconFromDB(page_url, icon_types, &favicon_data);
1926
1927 // TODO(pkotwicz): Pass in matched icon URLs for icon_types instead of empty
1928 // vector.
1929 request->ForwardResult(request->handle(), favicon_data, std::vector<GURL>());
1930 }
1931
1932 void HistoryBackend::SetFavicon(
1933 const GURL& page_url, 1986 const GURL& page_url,
1934 const GURL& icon_url, 1987 const GURL& icon_url,
1935 scoped_refptr<base::RefCountedMemory> data, 1988 IconType icon_type,
1936 IconType icon_type) { 1989 const std::vector<FaviconBitmapData>& favicon_bitmaps,
1937 DCHECK(data.get()); 1990 const IconURLSizesMap& icon_url_sizes) {
1938 if (!thumbnail_db_.get() || !db_.get()) 1991 /*if (!thumbnail_db_.get() || !db_.get())
1939 return; 1992 return;
1940 1993
1941 FaviconID id = thumbnail_db_->GetFaviconIDForFaviconURL( 1994 DCHECK(ValidateSetFaviconsParams(elements, icon_url_sizes));
1942 icon_url, icon_type, NULL); 1995
1943 if (id) 1996 // Build map of |elements| for icon url.
1944 thumbnail_db_->DeleteFaviconBitmapsForFavicon(id); 1997 typedef std::map<GURL, std::vector<FaviconBitmapData> > BitmapDataByIconURL;
1945 1998 BitmapDataByIconURL grouped_by_icon_url;
1946 id = thumbnail_db_->AddFavicon(icon_url, 1999 for (size_t i = 0; i < elements.size(); ++i) {
1947 icon_type, 2000 const GURL& icon_url = elements[i].icon_url;
1948 "0 0", 2001 grouped_by_icon_url[icon_url].push_back(elements[i]);
1949 data, 2002 }
1950 Time::Now(), 2003
1951 gfx::Size()); 2004 IconURLFaviconIDMap icon_url_id_map;
1952 2005 for (ElementsByIconURL::iterator it = grouped_by_icon_url.begin();
1953 SetFaviconMapping(page_url, id, icon_type); 2006 it != grouped_by_icon_url.end(); ++it) {
1954 } 2007 const GURL& icon_url = it->first;
1955 2008 FaviconID icon_id =
1956 void HistoryBackend::SetFaviconMapping(const GURL& page_url, 2009 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type);
1957 FaviconID id, 2010 if (!icon_id)
1958 IconType icon_type) { 2011 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type);
2012 icon_url_id_map[icon_url] = icon_id;
2013
2014 // Update sizes first because it may result in deleting favicon bitmaps.
2015 SetFaviconSizes(icon_id, icon_url_sizes.find(icon_url)->second);
2016 SetFaviconBitmaps(icon_id, it->second);
2017 }
2018
2019 // Update sizes for favicons which have entries in |icon_url_sizes| but not
2020 // in |elements|.
2021 for (IconURLSizesMap::const_iterator it = icon_url_sizes.begin();
2022 it != icon_url_sizes.end(); ++it) {
2023 const GURL& icon_url = it->first;
2024 if (grouped_by_icon_url.find(icon_url) == grouped_by_icon_url.end()) {
2025 FaviconID icon_id =
2026 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type);
2027 if (!icon_id)
2028 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type);
2029 icon_url_id_map[icon_url] = icon_id;
2030 SetFaviconSizes(icon_id, it->second);
2031 }
2032 }
2033
2034 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_url_id_map);
2035 */
2036 }
2037
2038 void HistoryBackend::SetFaviconBitmaps(
2039 FaviconID icon_id,
2040 const std::vector<FaviconBitmapData>& favicon_bitmaps) {
2041 /*
2042 std::vector<FaviconBitmapIDSize> bitmap_id_size_listing;
2043 thumbnail_db_->GetFaviconBitmapIDSizeListing(icon_id,
2044 &bitmap_id_size_listing);
2045
2046 // A nested loop is ok because in practice neither |elements| nor
2047 // |bitmap_id_size_listing| will have many elements.
2048 for (size_t i = 0; i < elements.size(); ++i) {
2049 const FaviconDataElement& element = elements[i];
2050 FaviconBitmapID bitmap_id = 0;
2051 for (size_t j = 0; j < bitmap_id_size_listing.size(); ++j) {
2052 if (bitmap_id_size_listing[j].pixel_size == element.pixel_size) {
2053 bitmap_id = bitmap_id_size_listing[j].bitmap_id;
2054 break;
2055 }
2056 }
2057 if (bitmap_id) {
2058 thumbnail_db_->SetFaviconBitmap(bitmap_id, element.bitmap_data,
2059 base::Time::Now());
2060 } else {
2061 thumbnail_db_->AddFaviconBitmap(icon_id, element.bitmap_data,
2062 base::Time::Now(), element.pixel_size);
2063 }
2064 }
2065 */
2066 }
2067
2068 bool HistoryBackend::ValidateSetFaviconsParams(
2069 const std::vector<FaviconBitmapData>& favicon_bitmaps,
2070 const IconURLSizesMap& icon_url_sizes) const {
2071 /*if (single_favicon_bitmap_per_icon_type_) {
2072 if (icon_url_sizes.size() != favicon_bitmaps.size())
2073 return false;
2074
2075 if (icon_url_sizes.size() > 1)
2076 return false;
2077
2078 if (icon_url_sizes.size() == 1) {
2079 const FaviconSizes& sizes = icon_url_sizes.begin()->second;
2080 if (!sizes.num_sizes() != 1 || !sizes.has_size(gfx::Size()))
2081 return false;
2082 }
2083 } else {
2084 if (icon_url_sizes.size() > kMaxFaviconsPerPage)
2085 return false;
2086 for (IconURLSizesMap::const_iterator it = icon_url_sizes.begin();
2087 it != icon_url_sizes.end(); ++it) {
2088 if (it->second.num_sizes() > kMaxFaviconBitmapsPerIconURL)
2089 return false;
2090 }
2091 }
2092
2093 for (size_t i = 0; i < favicon_bitmaps.size(); ++i) {
2094 IconURLSizesMap::const_iterator it =
2095 icon_url_sizes.find(favicon_bitmaps[i].icon_url);
2096 if (it == favicon_bitmaps.end() ||
2097 !it->second.has_size(favicon_bitmaps[i].pixel_size) ||
2098 !favicon_bitmaps[i].bitmap_data.get())
2099 return false;
2100 }
2101 */
2102 return true;
2103 }
2104
2105 void HistoryBackend::SetFaviconSizes(
2106 FaviconID icon_id,
2107 const FaviconSizes& sizes) {
2108 /*std::vector<FaviconBitmapIDSize> bitmap_id_size_listing;
2109 thumbnail_db_->GetFaviconBitmapIDSizeListing(icon_id,
2110 &bitmap_id_size_listing);
2111
2112 // Remove bitmaps whose pixel size is not contained in |sizes|.
2113 for (size_t i = 0; i < bitmap_id_size_listing.size(); ++i) {
2114 const gfx::Size& pixel_size = bitmap_id_size_listing[i].pixel_size;
2115 if (!sizes.has_size(pixel_size))
2116 thumbnail_db_->DeleteFaviconBitmap(bitmap_id_size_listing[i].bitmap_id);
2117 }
2118
2119 thumbnail_db_->SetFaviconSizes(icon_id, sizes.ToString());*/
2120 }
2121
2122 bool HistoryBackend::GetFaviconFromDB(
2123 const GURL& page_url,
2124 int icon_types,
2125 const gfx::Size& desired_dip_size,
2126 const std::vector<ui::ScaleFactor>& desired_scale_factors,
2127 FaviconData* favicon_data,
2128 std::vector<GURL>* mapped_icon_urls) {
2129 DCHECK(favicon_data);
2130
2131 if (!db_.get() || !thumbnail_db_.get())
2132 return false;
2133
2134 // Time the query.
2135 TimeTicks beginning_time = TimeTicks::Now();
2136
2137 std::vector<IconMapping> icon_mappings;
2138 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_types,
2139 &icon_mappings);
2140
2141 std::vector<FaviconID> favicon_ids;
sky 2012/08/24 16:35:42 Add a description as to what this does.
2142 std::vector<GURL> icon_urls;
2143 for (size_t i = 0; i < icon_mappings.size(); ++i) {
2144 favicon_ids.push_back(icon_mappings[i].icon_id);
2145 mapped_icon_urls->push_back(icon_mappings[i].icon_url);
2146 }
2147
2148 bool no_errors = GetFaviconDataForBestMatch(favicon_ids, desired_dip_size,
2149 desired_scale_factors, favicon_data);
2150
2151 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name
2152 TimeTicks::Now() - beginning_time);
2153 return no_errors && !mapped_icon_urls->empty();
2154 }
2155
2156 bool HistoryBackend::GetFaviconDataForBestMatch(
2157 const std::vector<FaviconID>& candidate_favicon_ids,
2158 const gfx::Size& desired_dip_size,
2159 const std::vector<ui::ScaleFactor>& desired_scale_factors,
2160 FaviconData* favicon_data) {
2161 if (candidate_favicon_ids.empty())
2162 return false;
2163
2164 // Find best match given |desired_dip_size| and |desired_scale_factors|.
2165 FaviconID best_favicon_id = 0;
2166 scoped_ptr<std::vector<FaviconBitmapID> > best_bitmap_ids(NULL);
sky 2012/08/24 16:35:42 Why do you need a scoped_ptr here and below?
2167 float highest_score = -1.0f;
2168 for (size_t i = 0; i < candidate_favicon_ids.size(); ++i) {
2169 scoped_ptr<std::vector<FaviconBitmapID> > candidate_bitmap_ids(
2170 new std::vector<FaviconBitmapID>());
2171 float score;
2172 std::vector<FaviconBitmapIDSize> bitmap_id_size_list;
2173 thumbnail_db_->GetFaviconBitmapIDSizeList(candidate_favicon_ids[i],
2174 &bitmap_id_size_list);
2175 // Currently only support requesting square favicons.
2176 SelectFaviconBitmapIDs(bitmap_id_size_list,
2177 desired_scale_factors,
2178 desired_dip_size.width(),
2179 candidate_bitmap_ids.get(),
2180 &score);
2181 if (score > highest_score) {
2182 best_favicon_id = candidate_favicon_ids[i],
2183 best_bitmap_ids.swap(candidate_bitmap_ids);
sky 2012/08/24 16:35:42 This seems like it only picks bitmaps for a unique
pkotwicz 2012/09/04 16:18:36 Yes this is true. I added a TODO to make this diff
sky 2012/09/04 17:18:07 Huh? Use swap if you're really worried.
2184 highest_score = score;
2185 }
2186 }
2187
2188 // Construct FaviconData from |best_favicon_id| and |best_bitmap_ids|.
2189 if (!thumbnail_db_->GetFaviconHeader(best_favicon_id,
2190 &favicon_data->icon_url,
2191 &favicon_data->icon_type,
2192 &favicon_data->sizes)) {
2193 return false;
2194 }
2195
2196 favicon_data->bitmaps.clear();
2197 for (size_t i = 0; i < best_bitmap_ids->size(); ++i) {
2198 base::Time last_updated;
2199 FaviconBitmapData favicon_bitmap_data;
2200 if (!thumbnail_db_->GetFaviconBitmap((*best_bitmap_ids)[i],
2201 &last_updated,
2202 &favicon_bitmap_data.bitmap_data,
2203 &favicon_bitmap_data.pixel_size)) {
2204 return false;
2205 }
2206
2207 favicon_bitmap_data.expired = (Time::Now() - last_updated) >
2208 TimeDelta::FromDays(kFaviconRefetchDays);
2209 favicon_data->bitmaps.push_back(favicon_bitmap_data);
2210 }
2211
2212 favicon_data->known_icon = true;
2213 return true;
2214 }
2215
2216 void HistoryBackend::SetFaviconMappingsForPageAndRedirects(
2217 const GURL& page_url,
2218 IconType icon_type,
2219 const IconURLFaviconIDMap& icon_url_id_map) {
1959 if (!thumbnail_db_.get()) 2220 if (!thumbnail_db_.get())
1960 return; 2221 return;
1961 2222
1962 // Find all the pages whose favicons we should set, we want to set it for 2223 // Find all the pages whose favicons we should set, we want to set it for
1963 // all the pages in the redirect chain if it redirected. 2224 // all the pages in the redirect chain if it redirected.
1964 history::RedirectList dummy_list; 2225 history::RedirectList dummy_list;
1965 history::RedirectList* redirects; 2226 history::RedirectList* redirects;
1966 RedirectCache::iterator iter = recent_redirects_.Get(page_url); 2227 RedirectCache::iterator iter = recent_redirects_.Get(page_url);
1967 if (iter != recent_redirects_.end()) { 2228 if (iter != recent_redirects_.end()) {
1968 redirects = &iter->second; 2229 redirects = &iter->second;
1969 2230
1970 // This redirect chain should have the destination URL as the last item. 2231 // This redirect chain should have the destination URL as the last item.
1971 DCHECK(!redirects->empty()); 2232 DCHECK(!redirects->empty());
1972 DCHECK(redirects->back() == page_url); 2233 DCHECK(redirects->back() == page_url);
1973 } else { 2234 } else {
1974 // No redirect chain stored, make up one containing the URL we want to we 2235 // No redirect chain stored, make up one containing the URL we want to we
1975 // can use the same logic below. 2236 // can use the same logic below.
1976 dummy_list.push_back(page_url); 2237 dummy_list.push_back(page_url);
1977 redirects = &dummy_list; 2238 redirects = &dummy_list;
1978 } 2239 }
1979 2240
1980 std::set<GURL> favicons_changed; 2241 std::set<GURL> favicons_changed;
1981 2242
1982 // Save page <-> favicon association. 2243 // Save page <-> favicon associations.
1983 for (history::RedirectList::const_iterator i(redirects->begin()); 2244 for (history::RedirectList::const_iterator i(redirects->begin());
1984 i != redirects->end(); ++i) { 2245 i != redirects->end(); ++i) {
1985 FaviconID replaced_id; 2246 if (SetFaviconMappingsForPage(*i, icon_type, icon_url_id_map)) {
1986 if (AddOrUpdateIconMapping(*i, id, icon_type, &replaced_id)) {
1987 // The page's favicon ID changed. This means that the one we just
1988 // changed from could have been orphaned, and we need to re-check it.
1989 // This is not super fast, but this case will get triggered rarely,
1990 // since normally a page will always map to the same favicon ID. It
1991 // will mostly happen for favicons we import.
1992 if (replaced_id && !thumbnail_db_->HasMappingFor(replaced_id))
1993 thumbnail_db_->DeleteFavicon(replaced_id);
1994
1995 favicons_changed.insert(*i); 2247 favicons_changed.insert(*i);
1996 } 2248 }
1997 } 2249 }
1998 2250
1999 // Send the notification about the changed favicons. 2251 // Send the notification about the changed favicons.
2000 FaviconChangeDetails* changed_details = new FaviconChangeDetails; 2252 FaviconChangeDetails* changed_details = new FaviconChangeDetails;
2001 changed_details->urls.swap(favicons_changed); 2253 changed_details->urls.swap(favicons_changed);
2002 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, 2254 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED,
2003 changed_details); 2255 changed_details);
2004 2256
2005 ScheduleCommit(); 2257 ScheduleCommit();
2006 } 2258 }
2007 2259
2008 bool HistoryBackend::AddOrUpdateIconMapping(const GURL& page_url, 2260 bool HistoryBackend::SetFaviconMappingsForPage(
2009 FaviconID id, 2261 const GURL& page_url,
2010 IconType icon_type, 2262 IconType icon_type,
2011 FaviconID* replaced_icon) { 2263 const IconURLFaviconIDMap& icon_url_id_map) {
2012 *replaced_icon = 0; 2264 DCHECK_LE(icon_url_id_map.size(), kMaxFaviconsPerPage);
2265 bool mappings_changed = false;
2266
2267 IconURLFaviconIDMap icon_mappings_to_add = icon_url_id_map;
2268
2269 // Two icon types are considered 'equivalent' if
2270 // a. The two icon types are equal.
2271 // b. If one of the icon types is ICON_TOUCH and the other is
2272 // ICON_PRECOMPOSED_TOUCH.
2273 //
2274 // For each of the urls in |icon_url_id_map|.
2275 // a. If one of the icon mappings has the same icon url as the url from
2276 // |icon_url_id_map|.
2277 // i. If the matched icon mapping has the same type as the given
2278 // |icon_type|, the icon mapping was previously created.
2279 // ii. If the matched icon mapping has an 'equivalent' icon type to the
2280 // given |icon_type|, update the icon mapping.
2281 // b. Otherwise, add the icon mapping represented by the url.
2282 // c. If there are any icon mappings with an icon_url not in
2283 // |icon_url_id_map| and the mapping type is the same or equivalent to the
2284 // given |icon_type|, remove the mapping.
2285
2013 std::vector<IconMapping> icon_mappings; 2286 std::vector<IconMapping> icon_mappings;
2014 if (!thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) { 2287 thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings);
2015 // There is no mapping add it directly.
2016 thumbnail_db_->AddIconMapping(page_url, id);
2017 return true;
2018 }
2019 // Iterate all matched icon mappings,
2020 // a. If the given icon id and matched icon id are same, return.
2021 // b. If the given icon type and matched icon type are same, but icon id
2022 // are not, update the IconMapping.
2023 // c. If the given icon_type and matched icon type are not same, but
2024 // either of them is ICON_TOUCH or ICON_PRECOMPOSED_TOUCH, update the
2025 // IconMapping.
2026 // d. Otherwise add a icon mapping.
2027 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); 2288 for (std::vector<IconMapping>::iterator m = icon_mappings.begin();
2028 m != icon_mappings.end(); ++m) { 2289 m != icon_mappings.end(); ++m) {
2029 if (m->icon_id == id)
2030 // The mapping is already there.
2031 return false;
2032
2033 if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) || 2290 if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) ||
2034 (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) || 2291 (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) ||
2035 (icon_type == m->icon_type)) { 2292 (icon_type == m->icon_type)) {
2036 thumbnail_db_->UpdateIconMapping(m->mapping_id, id); 2293 IconURLFaviconIDMap::iterator it =
2037 *replaced_icon = m->icon_id; 2294 icon_mappings_to_add.find(m->icon_url);
2038 return true; 2295 if (it == icon_mappings_to_add.end()) {
2296 thumbnail_db_->DeleteIconMapping(m->mapping_id);
2297 } else {
2298 icon_mappings_to_add.erase(it);
2299 if (icon_type == m->icon_type) {
2300 // The mapping is already there.
2301 continue;
2302 }
2303 thumbnail_db_->UpdateIconMapping(m->mapping_id, it->second);
2304 }
2305 // Removing / updating the icon mapping may have orphaned the associated
2306 // favicon so we must recheck it. This is not super fast, but this case
2307 // will get triggered rarely, since normally a page will always map to
2308 // the same favicon IDs. It will mostly happen for favicons we import.
2309 if (!thumbnail_db_->HasMappingFor(m->icon_id))
2310 thumbnail_db_->DeleteFavicon(m->icon_id);
2311
2312 mappings_changed = true;
2039 } 2313 }
2040 } 2314 }
2041 thumbnail_db_->AddIconMapping(page_url, id); 2315
2042 return true; 2316 for (IconURLFaviconIDMap::iterator it = icon_mappings_to_add.begin();
2317 it != icon_mappings_to_add.end(); ++it) {
2318 thumbnail_db_->AddIconMapping(page_url, it->second);
2319 mappings_changed = true;
2320 }
2321 return mappings_changed;
2043 } 2322 }
2044 2323
2045 void HistoryBackend::Commit() { 2324 void HistoryBackend::Commit() {
2046 if (!db_.get()) 2325 if (!db_.get())
2047 return; 2326 return;
2048 2327
2049 // Note that a commit may not actually have been scheduled if a caller 2328 // Note that a commit may not actually have been scheduled if a caller
2050 // explicitly calls this instead of using ScheduleCommit. Likewise, we 2329 // explicitly calls this instead of using ScheduleCommit. Likewise, we
2051 // may reset the flag written by a pending commit. But this is OK! It 2330 // may reset the flag written by a pending commit. But this is OK! It
2052 // will merely cause extra commits (which is kind of the idea). We 2331 // will merely cause extra commits (which is kind of the idea). We
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2416 2695
2417 return true; 2696 return true;
2418 } 2697 }
2419 2698
2420 BookmarkService* HistoryBackend::GetBookmarkService() { 2699 BookmarkService* HistoryBackend::GetBookmarkService() {
2421 if (bookmark_service_) 2700 if (bookmark_service_)
2422 bookmark_service_->BlockTillLoaded(); 2701 bookmark_service_->BlockTillLoaded();
2423 return bookmark_service_; 2702 return bookmark_service_;
2424 } 2703 }
2425 2704
2426 bool HistoryBackend::GetFaviconFromDB(
2427 const GURL& page_url,
2428 int icon_types,
2429 FaviconData* favicon_data) {
2430 DCHECK(favicon_data);
2431
2432 if (!db_.get() || !thumbnail_db_.get())
2433 return false;
2434
2435 bool success = false;
2436 // Time the query.
2437 TimeTicks beginning_time = TimeTicks::Now();
2438
2439 std::vector<IconMapping> icon_mappings;
2440 // Iterate over the known icons looking for one that includes one of the
2441 // requested types.
2442 if (thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) {
2443 for (std::vector<IconMapping>::iterator i = icon_mappings.begin();
2444 i != icon_mappings.end(); ++i) {
2445 if ((i->icon_type & icon_types) &&
2446 GetFaviconFromDB(i->icon_id, favicon_data)) {
2447 success = true;
2448 break;
2449 }
2450 }
2451 }
2452 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name
2453 TimeTicks::Now() - beginning_time);
2454 return success;
2455 }
2456
2457 bool HistoryBackend::GetFaviconFromDB(FaviconID favicon_id,
2458 FaviconData* favicon_data) {
2459 Time last_updated;
2460 scoped_refptr<base::RefCountedMemory> data;
2461
2462 favicon_data->known_icon = true;
2463 if (!thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data,
2464 &favicon_data->icon_url, &favicon_data->icon_type))
2465 return false;
2466
2467 FaviconBitmapData favicon_bitmap_data;
2468 favicon_bitmap_data.expired = (Time::Now() - last_updated) >
2469 TimeDelta::FromDays(kFaviconRefetchDays);
2470 favicon_bitmap_data.bitmap_data = data;
2471
2472 favicon_data->bitmaps.clear();
2473 favicon_data->bitmaps.push_back(favicon_bitmap_data);
2474 return true;
2475 }
2476
2477 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { 2705 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) {
2478 BriefVisitInfo info; 2706 BriefVisitInfo info;
2479 info.url_id = visit.url_id; 2707 info.url_id = visit.url_id;
2480 info.time = visit.visit_time; 2708 info.time = visit.visit_time;
2481 info.transition = visit.transition; 2709 info.transition = visit.transition;
2482 // If we don't have a delegate yet during setup or shutdown, we will drop 2710 // If we don't have a delegate yet during setup or shutdown, we will drop
2483 // these notifications. 2711 // these notifications.
2484 if (delegate_.get()) 2712 if (delegate_.get())
2485 delegate_->NotifyVisitDBObserversOnAddVisit(info); 2713 delegate_->NotifyVisitDBObserversOnAddVisit(info);
2486 } 2714 }
2487 2715
2488 } // namespace history 2716 } // namespace history
OLDNEW
« no previous file with comments | « chrome/browser/history/history_backend.h ('k') | chrome/browser/history/history_backend_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698