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 <list> | 7 #include <list> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 #include "chrome/browser/history/top_sites.h" | 29 #include "chrome/browser/history/top_sites.h" |
| 30 #include "chrome/browser/history/visit_filter.h" | 30 #include "chrome/browser/history/visit_filter.h" |
| 31 #include "chrome/common/chrome_constants.h" | 31 #include "chrome/common/chrome_constants.h" |
| 32 #include "chrome/common/chrome_notification_types.h" | 32 #include "chrome/common/chrome_notification_types.h" |
| 33 #include "chrome/common/url_constants.h" | 33 #include "chrome/common/url_constants.h" |
| 34 #include "content/public/browser/download_persistent_store_info.h" | 34 #include "content/public/browser/download_persistent_store_info.h" |
| 35 #include "googleurl/src/gurl.h" | 35 #include "googleurl/src/gurl.h" |
| 36 #include "grit/chromium_strings.h" | 36 #include "grit/chromium_strings.h" |
| 37 #include "grit/generated_resources.h" | 37 #include "grit/generated_resources.h" |
| 38 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 38 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 39 #include "ui/gfx/favicon_size.h" | |
| 39 | 40 |
| 40 #if defined(OS_ANDROID) | 41 #if defined(OS_ANDROID) |
| 41 #include "chrome/browser/history/android/android_provider_backend.h" | 42 #include "chrome/browser/history/android/android_provider_backend.h" |
| 42 #endif | 43 #endif |
| 43 | 44 |
| 44 using base::Time; | 45 using base::Time; |
| 45 using base::TimeDelta; | 46 using base::TimeDelta; |
| 46 using base::TimeTicks; | 47 using base::TimeTicks; |
| 47 | 48 |
| 48 /* The HistoryBackend consists of a number of components: | 49 /* The HistoryBackend consists of a number of components: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 favicon bitmaps stored for a single page. | |
| 99 const size_t kMaxFaviconsPerPage = 30; | |
| 100 | |
| 97 // Converts from PageUsageData to MostVisitedURL. |redirects| is a | 101 // Converts from PageUsageData to MostVisitedURL. |redirects| is a |
| 98 // list of redirects for this URL. Empty list means no redirects. | 102 // list of redirects for this URL. Empty list means no redirects. |
| 99 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, | 103 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, |
| 100 const RedirectList& redirects) { | 104 const RedirectList& redirects) { |
| 101 MostVisitedURL mv; | 105 MostVisitedURL mv; |
| 102 mv.url = page_data.GetURL(); | 106 mv.url = page_data.GetURL(); |
| 103 mv.title = page_data.GetTitle(); | 107 mv.title = page_data.GetTitle(); |
| 104 if (redirects.empty()) { | 108 if (redirects.empty()) { |
| 105 // Redirects must contain at least the target url. | 109 // Redirects must contain at least the target url. |
| 106 mv.redirects.push_back(mv.url); | 110 mv.redirects.push_back(mv.url); |
| (...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1766 success = thumbnail_db_->GetPageThumbnail(url_id, data); | 1770 success = thumbnail_db_->GetPageThumbnail(url_id, data); |
| 1767 } | 1771 } |
| 1768 } | 1772 } |
| 1769 } | 1773 } |
| 1770 | 1774 |
| 1771 return success; | 1775 return success; |
| 1772 } | 1776 } |
| 1773 | 1777 |
| 1774 void HistoryBackend::GetFavicon(scoped_refptr<GetFaviconRequest> request, | 1778 void HistoryBackend::GetFavicon(scoped_refptr<GetFaviconRequest> request, |
| 1775 const GURL& icon_url, | 1779 const GURL& icon_url, |
| 1780 const gfx::Size& pixel_size, | |
| 1776 int icon_types) { | 1781 int icon_types) { |
| 1777 UpdateFaviconMappingAndFetchImpl(NULL, icon_url, request, icon_types); | 1782 UpdateFaviconMappingAndFetchImpl(NULL, icon_url, request, pixel_size, |
| 1783 icon_types); | |
| 1778 } | 1784 } |
| 1779 | 1785 |
| 1780 void HistoryBackend::UpdateFaviconMappingAndFetch( | 1786 void HistoryBackend::UpdateFaviconMappingAndFetch( |
| 1781 scoped_refptr<GetFaviconRequest> request, | 1787 scoped_refptr<GetFaviconRequest> request, |
| 1782 const GURL& page_url, | 1788 const GURL& page_url, |
| 1783 const GURL& icon_url, | 1789 const GURL& icon_url, |
| 1790 const gfx::Size& pixel_size, | |
| 1784 IconType icon_type) { | 1791 IconType icon_type) { |
| 1785 UpdateFaviconMappingAndFetchImpl(&page_url, icon_url, request, icon_type); | 1792 UpdateFaviconMappingAndFetchImpl(&page_url, icon_url, request, pixel_size, |
| 1793 icon_type); | |
| 1786 } | 1794 } |
| 1787 | 1795 |
| 1788 void HistoryBackend::SetFaviconOutOfDateForPage(const GURL& page_url) { | 1796 void HistoryBackend::SetFaviconOutOfDateForPage(const GURL& page_url) { |
| 1789 std::vector<IconMapping> icon_mappings; | 1797 std::vector<IconMapping> icon_mappings; |
| 1790 | 1798 |
| 1791 if (!thumbnail_db_.get() || | 1799 if (!thumbnail_db_.get() || |
| 1792 !thumbnail_db_->GetIconMappingsForPageURL(page_url, | 1800 !thumbnail_db_->GetIconMappingsForPageURL(page_url, |
| 1793 &icon_mappings)) | 1801 &icon_mappings)) |
| 1794 return; | 1802 return; |
| 1795 | 1803 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1817 const std::vector<ImportedFaviconUsage>& favicon_usage) { | 1825 const std::vector<ImportedFaviconUsage>& favicon_usage) { |
| 1818 if (!db_.get() || !thumbnail_db_.get()) | 1826 if (!db_.get() || !thumbnail_db_.get()) |
| 1819 return; | 1827 return; |
| 1820 | 1828 |
| 1821 Time now = Time::Now(); | 1829 Time now = Time::Now(); |
| 1822 | 1830 |
| 1823 // Track all URLs that had their favicons set or updated. | 1831 // Track all URLs that had their favicons set or updated. |
| 1824 std::set<GURL> favicons_changed; | 1832 std::set<GURL> favicons_changed; |
| 1825 | 1833 |
| 1826 for (size_t i = 0; i < favicon_usage.size(); i++) { | 1834 for (size_t i = 0; i < favicon_usage.size(); i++) { |
| 1827 FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL( | 1835 std::vector<FaviconIDAndSize> favicon_id_size_listing; |
| 1828 favicon_usage[i].favicon_url, history::FAVICON, NULL); | 1836 thumbnail_db_->GetFaviconIDsForFaviconURL(favicon_usage[i].favicon_url, |
| 1829 if (!favicon_id) { | 1837 history::FAVICON, &favicon_id_size_listing); |
| 1838 if (favicon_id_size_listing.empty()) { | |
| 1830 // This favicon doesn't exist yet, so we create it using the given data. | 1839 // This favicon doesn't exist yet, so we create it using the given data. |
| 1831 favicon_id = thumbnail_db_->AddFavicon(favicon_usage[i].favicon_url, | 1840 gfx::Size default_size = |
| 1832 history::FAVICON); | 1841 gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); |
| 1842 FaviconID favicon_id = thumbnail_db_->AddFavicon( | |
| 1843 favicon_usage[i].favicon_url, default_size, history::FAVICON); | |
| 1833 if (!favicon_id) | 1844 if (!favicon_id) |
| 1834 continue; // Unable to add the favicon. | 1845 continue; // Unable to add the favicon. |
| 1835 thumbnail_db_->SetFavicon(favicon_id, | 1846 thumbnail_db_->SetFavicon(favicon_id, |
| 1836 new base::RefCountedBytes(favicon_usage[i].png_data), now); | 1847 new base::RefCountedBytes(favicon_usage[i].png_data), now); |
| 1848 | |
| 1849 FaviconIDAndSize favicon_id_size; | |
| 1850 favicon_id_size.icon_id = favicon_id; | |
| 1851 favicon_id_size.icon_size = default_size; | |
| 1852 favicon_id_size_listing.push_back(favicon_id_size); | |
| 1837 } | 1853 } |
| 1838 | 1854 |
| 1839 // Save the mapping from all the URLs to the favicon. | 1855 // Save the mapping from all the URLs to the favicon. |
| 1840 BookmarkService* bookmark_service = GetBookmarkService(); | 1856 BookmarkService* bookmark_service = GetBookmarkService(); |
| 1841 for (std::set<GURL>::const_iterator url = favicon_usage[i].urls.begin(); | 1857 for (std::set<GURL>::const_iterator url = favicon_usage[i].urls.begin(); |
| 1842 url != favicon_usage[i].urls.end(); ++url) { | 1858 url != favicon_usage[i].urls.end(); ++url) { |
| 1843 URLRow url_row; | 1859 URLRow url_row; |
| 1844 if (!db_->GetRowForURL(*url, &url_row)) { | 1860 if (!db_->GetRowForURL(*url, &url_row)) { |
| 1845 // If the URL is present as a bookmark, add the url in history to | 1861 // If the URL is present as a bookmark, add the url in history to |
| 1846 // save the favicon mapping. This will match with what history db does | 1862 // save the favicon mapping. This will match with what history db does |
| 1847 // for regular bookmarked URLs with favicons - when history db is | 1863 // for regular bookmarked URLs with favicons - when history db is |
| 1848 // cleaned, we keep an entry in the db with 0 visits as long as that | 1864 // cleaned, we keep an entry in the db with 0 visits as long as that |
| 1849 // url is bookmarked. | 1865 // url is bookmarked. |
| 1850 if (bookmark_service && bookmark_service_->IsBookmarked(*url)) { | 1866 if (bookmark_service && bookmark_service_->IsBookmarked(*url)) { |
| 1851 URLRow url_info(*url); | 1867 URLRow url_info(*url); |
| 1852 url_info.set_visit_count(0); | 1868 url_info.set_visit_count(0); |
| 1853 url_info.set_typed_count(0); | 1869 url_info.set_typed_count(0); |
| 1854 url_info.set_last_visit(base::Time()); | 1870 url_info.set_last_visit(base::Time()); |
| 1855 url_info.set_hidden(false); | 1871 url_info.set_hidden(false); |
| 1856 db_->AddURL(url_info); | 1872 db_->AddURL(url_info); |
| 1857 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1873 |
| 1874 for (std::vector<FaviconIDAndSize>::iterator favicon_id_size = | |
| 1875 favicon_id_size_listing.begin(); | |
| 1876 favicon_id_size != favicon_id_size_listing.end(); | |
| 1877 ++favicon_id_size) { | |
| 1878 thumbnail_db_->AddIconMapping(*url, favicon_id_size->icon_id); | |
| 1879 } | |
| 1858 favicons_changed.insert(*url); | 1880 favicons_changed.insert(*url); |
| 1859 } | 1881 } |
| 1860 } else { | 1882 } else { |
| 1861 if (!thumbnail_db_->GetIconMappingForPageURL(*url, FAVICON, NULL)) { | 1883 if (!thumbnail_db_->GetIconMappingsForPageURL(*url, FAVICON, NULL)) { |
| 1862 // URL is present in history, update the favicon *only* if it is not | 1884 // URL is present in history, update the favicon *only* if it is not |
| 1863 // set already. | 1885 // set already. |
| 1864 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1886 for (std::vector<FaviconIDAndSize>::iterator favicon_id_size = |
| 1887 favicon_id_size_listing.begin(); | |
| 1888 favicon_id_size != favicon_id_size_listing.end(); | |
| 1889 ++favicon_id_size) { | |
| 1890 thumbnail_db_->AddIconMapping(*url, favicon_id_size->icon_id); | |
| 1891 } | |
| 1865 favicons_changed.insert(*url); | 1892 favicons_changed.insert(*url); |
| 1866 } | 1893 } |
| 1867 } | 1894 } |
| 1868 } | 1895 } |
| 1869 } | 1896 } |
| 1870 | 1897 |
| 1871 if (!favicons_changed.empty()) { | 1898 if (!favicons_changed.empty()) { |
| 1872 // Send the notification about the changed favicon URLs. | 1899 // Send the notification about the changed favicon URLs. |
| 1873 FaviconChangeDetails* changed_details = new FaviconChangeDetails; | 1900 FaviconChangeDetails* changed_details = new FaviconChangeDetails; |
| 1874 changed_details->urls.swap(favicons_changed); | 1901 changed_details->urls.swap(favicons_changed); |
| 1875 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, | 1902 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, |
| 1876 changed_details); | 1903 changed_details); |
| 1877 } | 1904 } |
| 1878 } | 1905 } |
| 1879 | 1906 |
| 1880 void HistoryBackend::UpdateFaviconMappingAndFetchImpl( | 1907 void HistoryBackend::UpdateFaviconMappingAndFetchImpl( |
| 1881 const GURL* page_url, | 1908 const GURL* page_url, |
| 1882 const GURL& icon_url, | 1909 const GURL& icon_url, |
| 1883 scoped_refptr<GetFaviconRequest> request, | 1910 scoped_refptr<GetFaviconRequest> request, |
| 1911 const gfx::Size& pixel_size, | |
| 1884 int icon_types) { | 1912 int icon_types) { |
| 1885 // Check only a single type was given when the page_url was specified. | 1913 // Check only a single type was given when the page_url was specified. |
| 1886 DCHECK(!page_url || (page_url && (icon_types == FAVICON || | 1914 DCHECK(!page_url || (page_url && (icon_types == FAVICON || |
| 1887 icon_types == TOUCH_ICON || icon_types == TOUCH_PRECOMPOSED_ICON))); | 1915 icon_types == TOUCH_ICON || icon_types == TOUCH_PRECOMPOSED_ICON))); |
| 1888 | 1916 |
| 1889 if (request->canceled()) | 1917 if (request->canceled()) |
| 1890 return; | 1918 return; |
| 1891 | 1919 |
| 1892 FaviconData favicon; | 1920 FaviconData favicon; |
| 1893 | 1921 |
| 1894 if (thumbnail_db_.get()) { | 1922 if (thumbnail_db_.get()) { |
| 1895 const FaviconID favicon_id = | 1923 std::vector<FaviconIDAndSize> favicon_id_size_listing; |
| 1896 thumbnail_db_->GetFaviconIDForFaviconURL( | 1924 thumbnail_db_->GetFaviconIDsForFaviconURL(icon_url, icon_types, |
| 1897 icon_url, icon_types, &favicon.icon_type); | 1925 &favicon_id_size_listing); |
| 1926 FaviconID favicon_id = GetFaviconID(favicon_id_size_listing, pixel_size); | |
| 1898 if (favicon_id) { | 1927 if (favicon_id) { |
| 1899 scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes(); | 1928 GetFaviconFromDB(favicon_id, &favicon); |
| 1900 favicon.known_icon = true; | 1929 if (page_url) { |
| 1901 Time last_updated; | 1930 SetFaviconMapping(*page_url, favicon_id, pixel_size, favicon.icon_type); |
| 1902 if (thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data->data(), | |
| 1903 NULL, NULL)) { | |
| 1904 favicon.expired = (Time::Now() - last_updated) > | |
| 1905 TimeDelta::FromDays(kFaviconRefetchDays); | |
| 1906 favicon.image_data = data; | |
| 1907 } | 1931 } |
| 1908 | |
| 1909 if (page_url) | |
| 1910 SetFaviconMapping(*page_url, favicon_id, favicon.icon_type); | |
| 1911 } | 1932 } |
| 1912 // else case, haven't cached entry yet. Caller is responsible for | 1933 // else case, haven't cached entry yet. Caller is responsible for |
| 1913 // downloading the favicon and invoking SetFavicon. | 1934 // downloading the favicon and invoking SetFavicon. |
| 1914 } | 1935 } |
| 1915 request->ForwardResult(request->handle(), favicon); | 1936 request->ForwardResult(request->handle(), favicon); |
| 1916 } | 1937 } |
| 1917 | 1938 |
| 1939 FaviconID HistoryBackend::GetFaviconID( | |
| 1940 const std::vector<FaviconIDAndSize>& favicon_id_size_listing, | |
| 1941 const gfx::Size& desired_pixel_size) const { | |
| 1942 // Give preference to favicon sizes which will result in downscaling rather | |
| 1943 // than upscaling. | |
| 1944 FaviconID closest_favicon_id = 0; | |
| 1945 gfx::Size closest_pixel_size; | |
| 1946 for (size_t i = 0; i < favicon_id_size_listing.size(); ++i) { | |
| 1947 gfx::Size size = favicon_id_size_listing[i].icon_size; | |
| 1948 if (closest_pixel_size.GetArea() < desired_pixel_size.GetArea() && | |
|
stevenjb
2012/08/01 00:00:31
Area may not be the best method for comparison. Fo
pkotwicz
2012/08/02 19:47:52
Agree
| |
| 1949 size.GetArea() > closest_pixel_size.GetArea()) { | |
| 1950 closest_favicon_id = favicon_id_size_listing[i].icon_id; | |
| 1951 closest_pixel_size = size; | |
| 1952 } else if (closest_pixel_size.GetArea() > desired_pixel_size.GetArea() && | |
| 1953 size.GetArea() < closest_pixel_size.GetArea() && | |
| 1954 size.GetArea() >= desired_pixel_size.GetArea()) { | |
| 1955 closest_favicon_id = favicon_id_size_listing[i].icon_id; | |
| 1956 closest_pixel_size = size; | |
| 1957 } | |
| 1958 | |
| 1959 if (closest_pixel_size == desired_pixel_size) | |
| 1960 break; | |
| 1961 } | |
| 1962 return closest_favicon_id; | |
| 1963 } | |
| 1964 | |
| 1918 void HistoryBackend::GetFaviconForURL( | 1965 void HistoryBackend::GetFaviconForURL( |
| 1919 scoped_refptr<GetFaviconRequest> request, | 1966 scoped_refptr<GetFaviconRequest> request, |
| 1920 const GURL& page_url, | 1967 const GURL& page_url, |
| 1968 const gfx::Size& pixel_size, | |
| 1921 int icon_types) { | 1969 int icon_types) { |
| 1922 if (request->canceled()) | 1970 if (request->canceled()) |
| 1923 return; | 1971 return; |
| 1924 | 1972 |
| 1925 FaviconData favicon; | 1973 FaviconData favicon; |
| 1926 | 1974 |
| 1927 // Get the favicon from DB. | 1975 // Get the favicon from DB. |
| 1928 GetFaviconFromDB(page_url, icon_types, &favicon); | 1976 GetFaviconFromDB(page_url, pixel_size, icon_types, &favicon); |
| 1929 | 1977 |
| 1930 request->ForwardResult(request->handle(), favicon); | 1978 request->ForwardResult(request->handle(), favicon); |
| 1931 } | 1979 } |
| 1932 | 1980 |
| 1933 void HistoryBackend::GetFaviconForID(scoped_refptr<GetFaviconRequest> request, | 1981 void HistoryBackend::GetFaviconForID(scoped_refptr<GetFaviconRequest> request, |
| 1934 FaviconID id) { | 1982 FaviconID id) { |
| 1935 if (request->canceled()) | 1983 if (request->canceled()) |
| 1936 return; | 1984 return; |
| 1937 | 1985 |
| 1938 FaviconData favicon; | 1986 FaviconData favicon; |
| 1939 GetFaviconFromDB(id, &favicon); | 1987 GetFaviconFromDB(id, &favicon); |
| 1940 request->ForwardResult(request->handle(), favicon); | 1988 request->ForwardResult(request->handle(), favicon); |
| 1941 } | 1989 } |
| 1942 | 1990 |
| 1943 void HistoryBackend::SetFavicon( | 1991 void HistoryBackend::SetFavicon( |
| 1944 const GURL& page_url, | 1992 const GURL& page_url, |
| 1945 const GURL& icon_url, | 1993 const GURL& icon_url, |
| 1946 scoped_refptr<base::RefCountedMemory> data, | 1994 scoped_refptr<base::RefCountedMemory> data, |
| 1995 const gfx::Size& requested_size, | |
| 1947 IconType icon_type) { | 1996 IconType icon_type) { |
| 1997 // For M22, store |requested_size| as the favicon's pixel size into the | |
| 1998 // favicon database table. | |
| 1999 // TODO(pkotwicz): Fix this. | |
| 1948 DCHECK(data.get()); | 2000 DCHECK(data.get()); |
| 1949 if (!thumbnail_db_.get() || !db_.get()) | 2001 if (!thumbnail_db_.get() || !db_.get()) |
| 1950 return; | 2002 return; |
| 1951 | 2003 |
| 1952 FaviconID id = thumbnail_db_->GetFaviconIDForFaviconURL( | 2004 std::vector<FaviconIDAndSize> favicon_id_size_listing; |
| 1953 icon_url, icon_type, NULL); | 2005 thumbnail_db_->GetFaviconIDsForFaviconURL(icon_url, icon_type, |
| 2006 &favicon_id_size_listing); | |
| 2007 | |
| 2008 FaviconID id = 0; | |
| 2009 for (size_t i = 0; i < favicon_id_size_listing.size(); ++i) { | |
| 2010 if (favicon_id_size_listing[i].icon_size == requested_size) { | |
| 2011 id = favicon_id_size_listing[i].icon_id; | |
| 2012 break; | |
| 2013 } | |
| 2014 } | |
| 2015 | |
| 1954 if (!id) | 2016 if (!id) |
| 1955 id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 2017 id = thumbnail_db_->AddFavicon(icon_url, requested_size, icon_type); |
| 1956 | |
| 1957 // Set the image data. | 2018 // Set the image data. |
| 1958 thumbnail_db_->SetFavicon(id, data, Time::Now()); | 2019 thumbnail_db_->SetFavicon(id, data, Time::Now()); |
| 1959 | 2020 |
| 1960 SetFaviconMapping(page_url, id, icon_type); | 2021 SetFaviconMapping(page_url, id, requested_size, icon_type); |
| 1961 } | 2022 } |
| 1962 | 2023 |
| 1963 void HistoryBackend::SetFaviconMapping(const GURL& page_url, | 2024 void HistoryBackend::SetFaviconMapping(const GURL& page_url, |
| 1964 FaviconID id, | 2025 FaviconID id, |
| 2026 const gfx::Size& pixel_size, | |
| 1965 IconType icon_type) { | 2027 IconType icon_type) { |
| 1966 if (!thumbnail_db_.get()) | 2028 if (!thumbnail_db_.get()) |
| 1967 return; | 2029 return; |
| 1968 | 2030 |
| 1969 // Find all the pages whose favicons we should set, we want to set it for | 2031 // Find all the pages whose favicons we should set, we want to set it for |
| 1970 // all the pages in the redirect chain if it redirected. | 2032 // all the pages in the redirect chain if it redirected. |
| 1971 history::RedirectList dummy_list; | 2033 history::RedirectList dummy_list; |
| 1972 history::RedirectList* redirects; | 2034 history::RedirectList* redirects; |
| 1973 RedirectCache::iterator iter = recent_redirects_.Get(page_url); | 2035 RedirectCache::iterator iter = recent_redirects_.Get(page_url); |
| 1974 if (iter != recent_redirects_.end()) { | 2036 if (iter != recent_redirects_.end()) { |
| 1975 redirects = &iter->second; | 2037 redirects = &iter->second; |
| 1976 | 2038 |
| 1977 // This redirect chain should have the destination URL as the last item. | 2039 // This redirect chain should have the destination URL as the last item. |
| 1978 DCHECK(!redirects->empty()); | 2040 DCHECK(!redirects->empty()); |
| 1979 DCHECK(redirects->back() == page_url); | 2041 DCHECK(redirects->back() == page_url); |
| 1980 } else { | 2042 } else { |
| 1981 // No redirect chain stored, make up one containing the URL we want to we | 2043 // No redirect chain stored, make up one containing the URL we want to we |
| 1982 // can use the same logic below. | 2044 // can use the same logic below. |
| 1983 dummy_list.push_back(page_url); | 2045 dummy_list.push_back(page_url); |
| 1984 redirects = &dummy_list; | 2046 redirects = &dummy_list; |
| 1985 } | 2047 } |
| 1986 | 2048 |
| 1987 std::set<GURL> favicons_changed; | 2049 std::set<GURL> favicons_changed; |
| 1988 | 2050 |
| 1989 // Save page <-> favicon association. | 2051 // Save page <-> favicon association. |
| 1990 for (history::RedirectList::const_iterator i(redirects->begin()); | 2052 for (history::RedirectList::const_iterator i(redirects->begin()); |
| 1991 i != redirects->end(); ++i) { | 2053 i != redirects->end(); ++i) { |
| 1992 FaviconID replaced_id; | 2054 FaviconID replaced_id; |
| 1993 if (AddOrUpdateIconMapping(*i, id, icon_type, &replaced_id)) { | 2055 if (AddOrUpdateIconMapping(*i, id, pixel_size, icon_type, &replaced_id)) { |
| 1994 // The page's favicon ID changed. This means that the one we just | 2056 // The page's favicon ID changed. This means that the one we just |
| 1995 // changed from could have been orphaned, and we need to re-check it. | 2057 // changed from could have been orphaned, and we need to re-check it. |
| 1996 // This is not super fast, but this case will get triggered rarely, | 2058 // This is not super fast, but this case will get triggered rarely, |
| 1997 // since normally a page will always map to the same favicon ID. It | 2059 // since normally a page will always map to the same favicon ID. It |
| 1998 // will mostly happen for favicons we import. | 2060 // will mostly happen for favicons we import. |
| 1999 if (replaced_id && !thumbnail_db_->HasMappingFor(replaced_id)) | 2061 if (replaced_id && !thumbnail_db_->HasMappingFor(replaced_id)) |
| 2000 thumbnail_db_->DeleteFavicon(replaced_id); | 2062 thumbnail_db_->DeleteFavicon(replaced_id); |
| 2001 | 2063 |
| 2002 favicons_changed.insert(*i); | 2064 favicons_changed.insert(*i); |
| 2003 } | 2065 } |
| 2004 } | 2066 } |
| 2005 | 2067 |
| 2006 // Send the notification about the changed favicons. | 2068 // Send the notification about the changed favicons. |
| 2007 FaviconChangeDetails* changed_details = new FaviconChangeDetails; | 2069 FaviconChangeDetails* changed_details = new FaviconChangeDetails; |
| 2008 changed_details->urls.swap(favicons_changed); | 2070 changed_details->urls.swap(favicons_changed); |
| 2009 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, | 2071 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, |
| 2010 changed_details); | 2072 changed_details); |
| 2011 | 2073 |
| 2012 ScheduleCommit(); | 2074 ScheduleCommit(); |
| 2013 } | 2075 } |
| 2014 | 2076 |
| 2015 bool HistoryBackend::AddOrUpdateIconMapping(const GURL& page_url, | 2077 bool HistoryBackend::AddOrUpdateIconMapping(const GURL& page_url, |
| 2016 FaviconID id, | 2078 FaviconID id, |
| 2079 const gfx::Size& pixel_size, | |
| 2017 IconType icon_type, | 2080 IconType icon_type, |
| 2018 FaviconID* replaced_icon) { | 2081 FaviconID* replaced_icon) { |
| 2019 *replaced_icon = 0; | 2082 *replaced_icon = 0; |
| 2020 std::vector<IconMapping> icon_mappings; | 2083 std::vector<IconMapping> icon_mappings; |
| 2021 if (!thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) { | 2084 if (!thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) { |
| 2022 // There is no mapping add it directly. | 2085 // There is no mapping add it directly. |
| 2023 thumbnail_db_->AddIconMapping(page_url, id); | 2086 thumbnail_db_->AddIconMapping(page_url, id); |
| 2024 return true; | 2087 return true; |
| 2025 } | 2088 } |
| 2026 // Iterate all matched icon mappings, | 2089 // Iterate all matched icon mappings, |
| 2027 // a. If the given icon id and matched icon id are same, return. | 2090 // a. If the given icon id and matched icon id are same, return. |
| 2028 // b. If the given icon type and matched icon type are same, but icon id | 2091 // b. If the given icon size and the matched icon size are the same and |
| 2029 // are not, update the IconMapping. | 2092 // either: |
| 2030 // c. If the given icon_type and matched icon type are not same, but | 2093 // i. the given icon type and the matched icon type are the same. |
| 2031 // either of them is ICON_TOUCH or ICON_PRECOMPOSED_TOUCH, update the | 2094 // ii. the given icon type and matched icon type are not the same |
| 2032 // IconMapping. | 2095 // but either of them is ICON_TOUCH or ICON_PRECOMPOSED_TOUCH. |
|
stevenjb
2012/08/01 00:00:31
Do we care about differentiating between touch and
pkotwicz
2012/08/02 19:47:52
I'll look into this.
| |
| 2033 // d. Otherwise add a icon mapping. | 2096 // update the IconMapping. |
| 2097 // c. If there are no matches, but the number of mappings for page url | |
| 2098 // has exceeded kMaxFaviconsPerPage, update an arbitrary mapping. This | |
| 2099 // is a last line of defense and this property should be enforced | |
| 2100 // elsewhere as well. | |
|
stevenjb
2012/08/01 00:00:31
This seems a bit arbitrary. Have we considered def
pkotwicz
2012/08/02 19:47:52
We are actually going to be doing this too.
It sti
| |
| 2101 // d. Otherwise add an icon mapping. | |
| 2102 | |
| 2034 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 2103 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
| 2035 m != icon_mappings.end(); ++m) { | 2104 m != icon_mappings.end(); ++m) { |
| 2036 if (m->icon_id == id) | 2105 if (m->icon_id == id) |
| 2037 // The mapping is already there. | 2106 // The mapping is already there. |
| 2038 return false; | 2107 return false; |
| 2039 | 2108 |
| 2040 if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) || | 2109 if (pixel_size == m->icon_pixel_size) { |
| 2041 (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) || | 2110 if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) || |
| 2042 (icon_type == m->icon_type)) { | 2111 (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) || |
| 2043 thumbnail_db_->UpdateIconMapping(m->mapping_id, id); | 2112 (icon_type == m->icon_type)) { |
| 2044 *replaced_icon = m->icon_id; | 2113 thumbnail_db_->UpdateIconMapping(m->mapping_id, id); |
| 2045 return true; | 2114 *replaced_icon = m->icon_id; |
| 2115 return true; | |
| 2116 } | |
| 2046 } | 2117 } |
| 2047 } | 2118 } |
| 2119 | |
| 2120 if (icon_mappings.size() >= kMaxFaviconsPerPage) { | |
| 2121 thumbnail_db_->UpdateIconMapping(icon_mappings[0].mapping_id, id); | |
| 2122 *replaced_icon = icon_mappings[0].icon_id; | |
|
stevenjb
2012/08/01 00:00:31
Shouldn't this logic be in AddIconMapping? It's no
pkotwicz
2012/08/02 19:47:52
I would rather not add extra SQL queries to AddIco
| |
| 2123 return true; | |
| 2124 } | |
| 2125 | |
| 2048 thumbnail_db_->AddIconMapping(page_url, id); | 2126 thumbnail_db_->AddIconMapping(page_url, id); |
| 2049 return true; | 2127 return true; |
| 2050 } | 2128 } |
| 2051 | 2129 |
| 2052 void HistoryBackend::Commit() { | 2130 void HistoryBackend::Commit() { |
| 2053 if (!db_.get()) | 2131 if (!db_.get()) |
| 2054 return; | 2132 return; |
| 2055 | 2133 |
| 2056 // Note that a commit may not actually have been scheduled if a caller | 2134 // Note that a commit may not actually have been scheduled if a caller |
| 2057 // explicitly calls this instead of using ScheduleCommit. Likewise, we | 2135 // explicitly calls this instead of using ScheduleCommit. Likewise, we |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2427 } | 2505 } |
| 2428 | 2506 |
| 2429 BookmarkService* HistoryBackend::GetBookmarkService() { | 2507 BookmarkService* HistoryBackend::GetBookmarkService() { |
| 2430 if (bookmark_service_) | 2508 if (bookmark_service_) |
| 2431 bookmark_service_->BlockTillLoaded(); | 2509 bookmark_service_->BlockTillLoaded(); |
| 2432 return bookmark_service_; | 2510 return bookmark_service_; |
| 2433 } | 2511 } |
| 2434 | 2512 |
| 2435 bool HistoryBackend::GetFaviconFromDB( | 2513 bool HistoryBackend::GetFaviconFromDB( |
| 2436 const GURL& page_url, | 2514 const GURL& page_url, |
| 2515 const gfx::Size& pixel_size, | |
| 2437 int icon_types, | 2516 int icon_types, |
| 2438 FaviconData* favicon) { | 2517 FaviconData* favicon) { |
| 2439 DCHECK(favicon); | 2518 DCHECK(favicon); |
| 2440 | 2519 |
| 2441 if (!db_.get() || !thumbnail_db_.get()) | 2520 if (!db_.get() || !thumbnail_db_.get()) |
| 2442 return false; | 2521 return false; |
| 2443 | 2522 |
| 2444 bool success = false; | 2523 bool success = false; |
| 2445 // Time the query. | 2524 // Time the query. |
| 2446 TimeTicks beginning_time = TimeTicks::Now(); | 2525 TimeTicks beginning_time = TimeTicks::Now(); |
| 2447 | 2526 |
| 2448 std::vector<IconMapping> icon_mappings; | 2527 std::vector<IconMapping> icon_mappings; |
| 2449 // Iterate over the known icons looking for one that includes one of the | 2528 if (thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_types, |
| 2450 // requested types. | 2529 &icon_mappings)) { |
| 2451 if (thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) { | 2530 std::vector<FaviconIDAndSize> favicon_id_size_listing; |
| 2452 for (std::vector<IconMapping>::iterator i = icon_mappings.begin(); | 2531 for (std::vector<IconMapping>::iterator i = icon_mappings.begin(); |
| 2453 i != icon_mappings.end(); ++i) { | 2532 i != icon_mappings.end(); ++i) { |
| 2454 if ((i->icon_type & icon_types) && | 2533 FaviconIDAndSize favicon_id_size; |
| 2455 GetFaviconFromDB(i->icon_id, favicon)) { | 2534 favicon_id_size.icon_id = i->icon_id; |
| 2456 success = true; | 2535 favicon_id_size.icon_size = i->icon_pixel_size; |
| 2457 break; | 2536 favicon_id_size_listing.push_back(favicon_id_size); |
| 2458 } | |
| 2459 } | 2537 } |
| 2538 FaviconID favicon_id = GetFaviconID(favicon_id_size_listing, pixel_size); | |
| 2539 | |
| 2540 if (favicon_id && GetFaviconFromDB(favicon_id, favicon)) | |
| 2541 success = true; | |
| 2460 } | 2542 } |
| 2461 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name | 2543 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name |
| 2462 TimeTicks::Now() - beginning_time); | 2544 TimeTicks::Now() - beginning_time); |
| 2463 return success; | 2545 return success; |
| 2464 } | 2546 } |
| 2465 | 2547 |
| 2466 bool HistoryBackend::GetFaviconFromDB(FaviconID favicon_id, | 2548 bool HistoryBackend::GetFaviconFromDB(FaviconID favicon_id, |
| 2467 FaviconData* favicon) { | 2549 FaviconData* favicon) { |
| 2468 Time last_updated; | 2550 Time last_updated; |
| 2469 scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes(); | 2551 scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes(); |
| 2470 | 2552 |
| 2553 favicon->known_icon = true; | |
| 2471 if (!thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data->data(), | 2554 if (!thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data->data(), |
| 2472 &favicon->icon_url, &favicon->icon_type)) | 2555 &favicon->icon_url, &favicon->requested_size, &favicon->icon_type)) |
| 2473 return false; | 2556 return false; |
| 2474 | 2557 |
| 2475 favicon->expired = (Time::Now() - last_updated) > | 2558 favicon->expired = (Time::Now() - last_updated) > |
| 2476 TimeDelta::FromDays(kFaviconRefetchDays); | 2559 TimeDelta::FromDays(kFaviconRefetchDays); |
| 2477 favicon->known_icon = true; | 2560 favicon->bitmap_data = data; |
| 2478 favicon->image_data = data; | |
| 2479 return true; | 2561 return true; |
| 2480 } | 2562 } |
| 2481 | 2563 |
| 2482 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { | 2564 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { |
| 2483 BriefVisitInfo info; | 2565 BriefVisitInfo info; |
| 2484 info.url_id = visit.url_id; | 2566 info.url_id = visit.url_id; |
| 2485 info.time = visit.visit_time; | 2567 info.time = visit.visit_time; |
| 2486 info.transition = visit.transition; | 2568 info.transition = visit.transition; |
| 2487 // If we don't have a delegate yet during setup or shutdown, we will drop | 2569 // If we don't have a delegate yet during setup or shutdown, we will drop |
| 2488 // these notifications. | 2570 // these notifications. |
| 2489 if (delegate_.get()) | 2571 if (delegate_.get()) |
| 2490 delegate_->NotifyVisitDBObserversOnAddVisit(info); | 2572 delegate_->NotifyVisitDBObserversOnAddVisit(info); |
| 2491 } | 2573 } |
| 2492 | 2574 |
| 2493 } // namespace history | 2575 } // namespace history |
| OLD | NEW |