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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 static const int kSessionCloseTimeWindowSecs = 10; | 87 static const int kSessionCloseTimeWindowSecs = 10; |
| 88 | 88 |
| 89 // The maximum number of items we'll allow in the redirect list before | 89 // The maximum number of items we'll allow in the redirect list before |
| 90 // deleting some. | 90 // deleting some. |
| 91 static const int kMaxRedirectCount = 32; | 91 static const int kMaxRedirectCount = 32; |
| 92 | 92 |
| 93 // The number of days old a history entry can be before it is considered "old" | 93 // The number of days old a history entry can be before it is considered "old" |
| 94 // and is archived. | 94 // and is archived. |
| 95 static const int kArchiveDaysThreshold = 90; | 95 static const int kArchiveDaysThreshold = 90; |
| 96 | 96 |
| 97 // The maximum number of icons URLs per page which can be stored in the | |
| 98 // thumbnail database. | |
| 99 const size_t kMaxFaviconsPerPage = 8; | |
| 100 | |
| 101 // The maximum number of bitmaps for a single icon URL which can be stored in | |
| 102 // the thumbnail database. | |
| 103 const size_t kMaxFaviconBitmapsPerIconURL = 8; | |
| 104 | |
| 97 // Converts from PageUsageData to MostVisitedURL. |redirects| is a | 105 // Converts from PageUsageData to MostVisitedURL. |redirects| is a |
| 98 // list of redirects for this URL. Empty list means no redirects. | 106 // list of redirects for this URL. Empty list means no redirects. |
| 99 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, | 107 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, |
| 100 const RedirectList& redirects) { | 108 const RedirectList& redirects) { |
| 101 MostVisitedURL mv; | 109 MostVisitedURL mv; |
| 102 mv.url = page_data.GetURL(); | 110 mv.url = page_data.GetURL(); |
| 103 mv.title = page_data.GetTitle(); | 111 mv.title = page_data.GetTitle(); |
| 104 if (redirects.empty()) { | 112 if (redirects.empty()) { |
| 105 // Redirects must contain at least the target url. | 113 // Redirects must contain at least the target url. |
| 106 mv.redirects.push_back(mv.url); | 114 mv.redirects.push_back(mv.url); |
| (...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1764 URLID url_id; | 1772 URLID url_id; |
| 1765 if ((url_id = db_->GetRowForURL(redirects.back(), NULL))) | 1773 if ((url_id = db_->GetRowForURL(redirects.back(), NULL))) |
| 1766 success = thumbnail_db_->GetPageThumbnail(url_id, data); | 1774 success = thumbnail_db_->GetPageThumbnail(url_id, data); |
| 1767 } | 1775 } |
| 1768 } | 1776 } |
| 1769 } | 1777 } |
| 1770 | 1778 |
| 1771 return success; | 1779 return success; |
| 1772 } | 1780 } |
| 1773 | 1781 |
| 1774 void HistoryBackend::GetFavicon(scoped_refptr<GetFaviconRequest> request, | 1782 void HistoryBackend::GetFavicons(scoped_refptr<GetFaviconRequest> request, |
| 1775 const GURL& icon_url, | 1783 const std::vector<GURL>& icon_urls, |
| 1776 int icon_types) { | 1784 int icon_types) { |
| 1777 UpdateFaviconMappingAndFetchImpl(NULL, icon_url, request, icon_types); | 1785 UpdateFaviconMappingsAndFetchImpl(NULL, icon_urls, request, icon_types); |
| 1778 } | 1786 } |
| 1779 | 1787 |
| 1780 void HistoryBackend::UpdateFaviconMappingAndFetch( | 1788 void HistoryBackend::GetFaviconsForURL( |
| 1781 scoped_refptr<GetFaviconRequest> request, | 1789 scoped_refptr<GetFaviconRequest> request, |
| 1782 const GURL& page_url, | 1790 const GURL& page_url, |
| 1783 const GURL& icon_url, | 1791 int icon_types) { |
| 1784 IconType icon_type) { | 1792 if (request->canceled()) |
| 1785 UpdateFaviconMappingAndFetchImpl(&page_url, icon_url, request, icon_type); | 1793 return; |
| 1794 | |
| 1795 FaviconData favicon_data; | |
| 1796 | |
| 1797 // Get the favicons from DB. | |
| 1798 GetFaviconsFromDB(page_url, icon_types, &favicon_data); | |
| 1799 | |
| 1800 request->ForwardResult(request->handle(), favicon_data); | |
| 1786 } | 1801 } |
| 1787 | 1802 |
| 1788 void HistoryBackend::SetFaviconOutOfDateForPage(const GURL& page_url) { | 1803 void HistoryBackend::UpdateFaviconMappingsAndFetch( |
| 1804 scoped_refptr<GetFaviconRequest> request, | |
| 1805 const GURL& page_url, | |
| 1806 const std::vector<GURL>& icon_urls, | |
| 1807 IconType icon_type) { | |
| 1808 UpdateFaviconMappingsAndFetchImpl(&page_url, icon_urls, request, icon_type); | |
| 1809 } | |
| 1810 | |
| 1811 void HistoryBackend::AddFavicons( | |
| 1812 const GURL& page_url, | |
| 1813 IconType icon_type, | |
| 1814 const std::vector<FaviconDataElement>& elements) { | |
| 1815 FaviconData favicon_data; | |
| 1816 GetFaviconsFromDB(page_url, icon_type, &favicon_data); | |
| 1817 | |
| 1818 IconURLSizesMap icon_url_sizes; | |
| 1819 if (favicon_data.known_icon) { | |
| 1820 icon_url_sizes = favicon_data.icon_url_sizes; | |
| 1821 } else { | |
| 1822 // The thumbnail database doesn't know about |page_url|. Guess at what | |
| 1823 // |icon_url_sizes| should be. | |
| 1824 for (size_t i = 0; i < elements.size(); ++i) { | |
| 1825 const GURL& icon_url = elements[i].icon_url; | |
| 1826 icon_url_sizes[icon_url].InsertSize(elements[i].pixel_size); | |
| 1827 } | |
| 1828 } | |
| 1829 | |
| 1830 SetFavicons(page_url, icon_type, elements, icon_url_sizes); | |
| 1831 } | |
| 1832 | |
| 1833 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { | |
| 1789 std::vector<IconMapping> icon_mappings; | 1834 std::vector<IconMapping> icon_mappings; |
| 1790 | 1835 |
| 1791 if (!thumbnail_db_.get() || | 1836 if (!thumbnail_db_.get() || |
| 1792 !thumbnail_db_->GetIconMappingsForPageURL(page_url, | 1837 !thumbnail_db_->GetIconMappingsForPageURL(page_url, |
| 1793 &icon_mappings)) | 1838 &icon_mappings)) |
| 1794 return; | 1839 return; |
| 1795 | 1840 |
| 1796 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 1841 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
| 1797 m != icon_mappings.end(); ++m) { | 1842 m != icon_mappings.end(); ++m) { |
| 1798 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); | 1843 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); |
| 1799 } | 1844 } |
| 1800 ScheduleCommit(); | 1845 ScheduleCommit(); |
| 1801 } | 1846 } |
| 1802 | 1847 |
| 1803 void HistoryBackend::CloneFavicon(const GURL& old_page_url, | 1848 void HistoryBackend::CloneFavicons(const GURL& old_page_url, |
| 1804 const GURL& new_page_url) { | 1849 const GURL& new_page_url) { |
| 1805 if (!thumbnail_db_.get()) | 1850 if (!thumbnail_db_.get()) |
| 1806 return; | 1851 return; |
| 1807 | 1852 |
| 1808 // Prevent cross-domain cloning. | 1853 // Prevent cross-domain cloning. |
| 1809 if (old_page_url.GetOrigin() != new_page_url.GetOrigin()) | 1854 if (old_page_url.GetOrigin() != new_page_url.GetOrigin()) |
| 1810 return; | 1855 return; |
| 1811 | 1856 |
| 1812 thumbnail_db_->CloneIconMapping(old_page_url, new_page_url); | 1857 thumbnail_db_->CloneIconMappings(old_page_url, new_page_url); |
| 1813 ScheduleCommit(); | 1858 ScheduleCommit(); |
| 1814 } | 1859 } |
| 1815 | 1860 |
| 1816 void HistoryBackend::SetImportedFavicons( | 1861 void HistoryBackend::SetImportedFavicons( |
| 1817 const std::vector<ImportedFaviconUsage>& favicon_usage) { | 1862 const std::vector<ImportedFaviconUsage>& favicon_usage) { |
| 1818 if (!db_.get() || !thumbnail_db_.get()) | 1863 if (!db_.get() || !thumbnail_db_.get()) |
| 1819 return; | 1864 return; |
| 1820 | 1865 |
| 1821 Time now = Time::Now(); | 1866 Time now = Time::Now(); |
| 1822 | 1867 |
| 1823 // Track all URLs that had their favicons set or updated. | 1868 // Track all URLs that had their favicons set or updated. |
| 1824 std::set<GURL> favicons_changed; | 1869 std::set<GURL> favicons_changed; |
| 1825 | 1870 |
| 1826 for (size_t i = 0; i < favicon_usage.size(); i++) { | 1871 for (size_t i = 0; i < favicon_usage.size(); i++) { |
| 1827 FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL( | 1872 FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL( |
| 1828 favicon_usage[i].favicon_url, history::FAVICON, NULL); | 1873 favicon_usage[i].favicon_url, history::FAVICON); |
| 1829 if (!favicon_id) { | 1874 if (!favicon_id) { |
| 1830 // This favicon doesn't exist yet, so we create it using the given data. | 1875 // This favicon doesn't exist yet, so we create it using the given data. |
| 1831 // TODO(pkotwicz): Pass in real pixel size. | 1876 // TODO(pkotwicz): Pass in real pixel size. |
| 1832 favicon_id = thumbnail_db_->AddFavicon( | 1877 favicon_id = thumbnail_db_->AddFavicon( |
| 1833 favicon_usage[i].favicon_url, | 1878 favicon_usage[i].favicon_url, |
| 1834 history::FAVICON, | 1879 history::FAVICON, |
| 1835 std::string("0 0"), | 1880 std::string("0 0"), |
| 1836 new base::RefCountedBytes(favicon_usage[i].png_data), | 1881 new base::RefCountedBytes(favicon_usage[i].png_data), |
| 1837 now, | 1882 now, |
| 1838 gfx::Size()); | 1883 gfx::Size()); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1853 URLRow url_info(*url); | 1898 URLRow url_info(*url); |
| 1854 url_info.set_visit_count(0); | 1899 url_info.set_visit_count(0); |
| 1855 url_info.set_typed_count(0); | 1900 url_info.set_typed_count(0); |
| 1856 url_info.set_last_visit(base::Time()); | 1901 url_info.set_last_visit(base::Time()); |
| 1857 url_info.set_hidden(false); | 1902 url_info.set_hidden(false); |
| 1858 db_->AddURL(url_info); | 1903 db_->AddURL(url_info); |
| 1859 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1904 thumbnail_db_->AddIconMapping(*url, favicon_id); |
| 1860 favicons_changed.insert(*url); | 1905 favicons_changed.insert(*url); |
| 1861 } | 1906 } |
| 1862 } else { | 1907 } else { |
| 1863 if (!thumbnail_db_->GetIconMappingForPageURL(*url, FAVICON, NULL)) { | 1908 if (!thumbnail_db_->GetIconMappingsForPageURL(*url, FAVICON, NULL)) { |
| 1864 // URL is present in history, update the favicon *only* if it is not | 1909 // URL is present in history, update the favicon *only* if it is not |
| 1865 // set already. | 1910 // set already. |
| 1866 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1911 thumbnail_db_->AddIconMapping(*url, favicon_id); |
| 1867 favicons_changed.insert(*url); | 1912 favicons_changed.insert(*url); |
| 1868 } | 1913 } |
| 1869 } | 1914 } |
| 1870 } | 1915 } |
| 1871 } | 1916 } |
| 1872 | 1917 |
| 1873 if (!favicons_changed.empty()) { | 1918 if (!favicons_changed.empty()) { |
| 1874 // Send the notification about the changed favicon URLs. | 1919 // Send the notification about the changed favicon URLs. |
| 1875 FaviconChangeDetails* changed_details = new FaviconChangeDetails; | 1920 FaviconChangeDetails* changed_details = new FaviconChangeDetails; |
| 1876 changed_details->urls.swap(favicons_changed); | 1921 changed_details->urls.swap(favicons_changed); |
| 1877 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, | 1922 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, |
| 1878 changed_details); | 1923 changed_details); |
| 1879 } | 1924 } |
| 1880 } | 1925 } |
| 1881 | 1926 |
| 1882 void HistoryBackend::UpdateFaviconMappingAndFetchImpl( | 1927 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( |
| 1883 const GURL* page_url, | 1928 const GURL* page_url, |
| 1884 const GURL& icon_url, | 1929 const std::vector<GURL>& icon_urls, |
| 1885 scoped_refptr<GetFaviconRequest> request, | 1930 scoped_refptr<GetFaviconRequest> request, |
| 1886 int icon_types) { | 1931 int icon_types) { |
| 1887 // Check only a single type was given when the page_url was specified. | 1932 // Check only a single type was given when the page_url was specified. |
| 1888 DCHECK(!page_url || (page_url && (icon_types == FAVICON || | 1933 DCHECK(!page_url || (page_url && (icon_types == FAVICON || |
| 1889 icon_types == TOUCH_ICON || icon_types == TOUCH_PRECOMPOSED_ICON))); | 1934 icon_types == TOUCH_ICON || icon_types == TOUCH_PRECOMPOSED_ICON))); |
| 1890 | 1935 |
| 1891 if (request->canceled()) | 1936 if (request->canceled()) |
| 1892 return; | 1937 return; |
| 1893 | 1938 |
| 1894 FaviconData favicon; | 1939 FaviconData favicon_data; |
| 1895 | 1940 IconURLFaviconIDMap icon_url_id_map; |
| 1896 if (thumbnail_db_.get()) { | 1941 if (thumbnail_db_.get()) { |
| 1897 const FaviconID favicon_id = | 1942 for (size_t i = 0; i < icon_urls.size(); ++i) { |
| 1898 thumbnail_db_->GetFaviconIDForFaviconURL( | 1943 const GURL& icon_url = icon_urls[i]; |
| 1899 icon_url, icon_types, &favicon.icon_type); | 1944 const FaviconID favicon_id = |
| 1900 if (favicon_id) { | 1945 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_types); |
| 1901 scoped_refptr<base::RefCountedMemory> data; | 1946 if (favicon_id) { |
| 1902 favicon.known_icon = true; | 1947 AddToFaviconData(favicon_id, &favicon_data); |
| 1903 Time last_updated; | 1948 icon_url_id_map[icon_url] = favicon_id; |
| 1904 if (thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data, | |
| 1905 NULL, NULL)) { | |
| 1906 favicon.expired = (Time::Now() - last_updated) > | |
| 1907 TimeDelta::FromDays(kFaviconRefetchDays); | |
| 1908 favicon.image_data = data; | |
| 1909 } | 1949 } |
| 1910 | 1950 // else case, haven't cached entry yet. Caller is responsible for |
| 1911 if (page_url) | 1951 // downloading the favicon and invoking SetFavicons. |
| 1912 SetFaviconMapping(*page_url, favicon_id, favicon.icon_type); | 1952 } |
| 1913 } | 1953 } |
| 1914 // else case, haven't cached entry yet. Caller is responsible for | 1954 |
| 1915 // downloading the favicon and invoking SetFavicon. | 1955 if (page_url) { |
| 1916 } | 1956 SetFaviconMappingsForPageAndRedirects( |
| 1917 request->ForwardResult(request->handle(), favicon); | 1957 *page_url, favicon_data.icon_type, icon_url_id_map); |
| 1918 } | 1958 } |
| 1919 | 1959 request->ForwardResult(request->handle(), favicon_data); |
| 1920 void HistoryBackend::GetFaviconForURL( | 1960 } |
| 1921 scoped_refptr<GetFaviconRequest> request, | 1961 |
| 1962 void HistoryBackend::SetFavicons( | |
| 1922 const GURL& page_url, | 1963 const GURL& page_url, |
| 1923 int icon_types) { | 1964 IconType icon_type, |
| 1924 if (request->canceled()) | 1965 const std::vector<FaviconDataElement>& elements, |
| 1925 return; | 1966 const IconURLSizesMap& icon_url_sizes) { |
| 1926 | |
| 1927 FaviconData favicon; | |
| 1928 | |
| 1929 // Get the favicon from DB. | |
| 1930 GetFaviconFromDB(page_url, icon_types, &favicon); | |
| 1931 | |
| 1932 request->ForwardResult(request->handle(), favicon); | |
| 1933 } | |
| 1934 | |
| 1935 void HistoryBackend::GetFaviconForID(scoped_refptr<GetFaviconRequest> request, | |
| 1936 FaviconID id) { | |
| 1937 if (request->canceled()) | |
| 1938 return; | |
| 1939 | |
| 1940 FaviconData favicon; | |
| 1941 GetFaviconFromDB(id, &favicon); | |
| 1942 request->ForwardResult(request->handle(), favicon); | |
| 1943 } | |
| 1944 | |
| 1945 void HistoryBackend::SetFavicon( | |
| 1946 const GURL& page_url, | |
| 1947 const GURL& icon_url, | |
| 1948 scoped_refptr<base::RefCountedMemory> data, | |
| 1949 IconType icon_type) { | |
| 1950 DCHECK(data.get()); | |
| 1951 if (!thumbnail_db_.get() || !db_.get()) | 1967 if (!thumbnail_db_.get() || !db_.get()) |
| 1952 return; | 1968 return; |
| 1953 | 1969 |
| 1954 FaviconID id = thumbnail_db_->GetFaviconIDForFaviconURL( | 1970 DCHECK(ValidateSetFaviconsParams(elements, icon_url_sizes)); |
| 1955 icon_url, icon_type, NULL); | 1971 |
| 1956 if (id) | 1972 // Build map of |elements| for icon url. |
| 1957 thumbnail_db_->DeleteFaviconBitmapsForFavicon(id); | 1973 typedef std::map<GURL, std::vector<FaviconDataElement> > ElementsByIconURL; |
| 1958 | 1974 ElementsByIconURL grouped_by_icon_url; |
| 1959 id = thumbnail_db_->AddFavicon(icon_url, | 1975 for (size_t i = 0; i < elements.size(); ++i) { |
| 1960 icon_type, | 1976 const GURL& icon_url = elements[i].icon_url; |
| 1961 "0 0", | 1977 grouped_by_icon_url[icon_url].push_back(elements[i]); |
| 1962 data, | 1978 } |
| 1963 Time::Now(), | 1979 |
| 1964 gfx::Size()); | 1980 IconURLFaviconIDMap icon_url_id_map; |
| 1965 | 1981 for (ElementsByIconURL::iterator it = grouped_by_icon_url.begin(); |
| 1966 SetFaviconMapping(page_url, id, icon_type); | 1982 it != grouped_by_icon_url.end(); ++it) { |
| 1967 } | 1983 const GURL& icon_url = it->first; |
| 1968 | 1984 FaviconID icon_id = |
| 1969 void HistoryBackend::SetFaviconMapping(const GURL& page_url, | 1985 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type); |
| 1970 FaviconID id, | 1986 if (!icon_id) |
| 1971 IconType icon_type) { | 1987 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
| 1988 icon_url_id_map[icon_url] = icon_id; | |
| 1989 | |
| 1990 // Update sizes first because it may result in deleting favicon bitmaps. | |
| 1991 SetFaviconSizes(icon_id, icon_url_sizes.find(icon_url)->second); | |
| 1992 SetFaviconBitmaps(icon_id, it->second); | |
| 1993 } | |
| 1994 | |
| 1995 // Update sizes for favicons which have entries in |icon_url_sizes| but not | |
| 1996 // in |elements|. | |
| 1997 for (IconURLSizesMap::const_iterator it = icon_url_sizes.begin(); | |
| 1998 it != icon_url_sizes.end(); ++it) { | |
| 1999 const GURL& icon_url = it->first; | |
| 2000 if (grouped_by_icon_url.find(icon_url) == grouped_by_icon_url.end()) { | |
| 2001 FaviconID icon_id = | |
| 2002 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type); | |
| 2003 if (!icon_id) | |
| 2004 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | |
| 2005 icon_url_id_map[icon_url] = icon_id; | |
| 2006 SetFaviconSizes(icon_id, it->second); | |
| 2007 } | |
| 2008 } | |
| 2009 | |
| 2010 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_url_id_map); | |
| 2011 } | |
| 2012 | |
| 2013 void HistoryBackend::SetFaviconBitmaps( | |
| 2014 FaviconID icon_id, | |
| 2015 const std::vector<FaviconDataElement>& elements) { | |
| 2016 std::vector<FaviconBitmapIDSize> bitmap_id_size_listing; | |
| 2017 thumbnail_db_->GetFaviconBitmapIDSizeListing(icon_id, | |
| 2018 &bitmap_id_size_listing); | |
| 2019 | |
| 2020 // A nested loop is ok because in practice neither |elements| nor | |
| 2021 // |bitmap_id_size_listing| will have many elements. | |
| 2022 for (size_t i = 0; i < elements.size(); ++i) { | |
| 2023 const FaviconDataElement& element = elements[i]; | |
| 2024 FaviconBitmapID bitmap_id = 0; | |
| 2025 for (size_t j = 0; j < bitmap_id_size_listing.size(); ++j) { | |
| 2026 if (bitmap_id_size_listing[j].pixel_size == element.pixel_size) { | |
| 2027 bitmap_id = bitmap_id_size_listing[j].bitmap_id; | |
| 2028 break; | |
| 2029 } | |
| 2030 } | |
| 2031 if (bitmap_id) { | |
| 2032 thumbnail_db_->SetFaviconBitmap(bitmap_id, element.bitmap_data, | |
| 2033 base::Time::Now()); | |
| 2034 } else { | |
| 2035 thumbnail_db_->AddFaviconBitmap(icon_id, element.bitmap_data, | |
| 2036 base::Time::Now(), element.pixel_size); | |
| 2037 } | |
| 2038 } | |
| 2039 } | |
| 2040 | |
| 2041 bool HistoryBackend::ValidateSetFaviconsParams( | |
| 2042 const std::vector<FaviconDataElement>& elements, | |
| 2043 const IconURLSizesMap& icon_url_sizes) const { | |
| 2044 if (single_favicon_bitmap_per_icon_type_) { | |
| 2045 if (icon_url_sizes.size() != elements.size()) | |
| 2046 return false; | |
| 2047 | |
| 2048 if (icon_url_sizes.size() > 1) | |
| 2049 return false; | |
| 2050 | |
| 2051 if (icon_url_sizes.size() == 1) { | |
| 2052 const FaviconSizes& sizes = icon_url_sizes.begin()->second; | |
| 2053 if (!sizes.num_sizes() != 1 || !sizes.has_size(gfx::Size())) | |
| 2054 return false; | |
| 2055 } | |
| 2056 } else { | |
| 2057 if (icon_url_sizes.size() > kMaxFaviconsPerPage) | |
| 2058 return false; | |
| 2059 for (IconURLSizesMap::const_iterator it = icon_url_sizes.begin(); | |
| 2060 it != icon_url_sizes.end(); ++it) { | |
| 2061 if (it->second.num_sizes() > kMaxFaviconBitmapsPerIconURL) | |
| 2062 return false; | |
| 2063 } | |
| 2064 } | |
| 2065 | |
| 2066 for (size_t i = 0; i < elements.size(); ++i) { | |
| 2067 IconURLSizesMap::const_iterator it = | |
| 2068 icon_url_sizes.find(elements[i].icon_url); | |
| 2069 if (it == icon_url_sizes.end() || | |
| 2070 !it->second.has_size(elements[i].pixel_size) || | |
| 2071 !elements[i].bitmap_data.get()) | |
| 2072 return false; | |
| 2073 } | |
| 2074 | |
| 2075 return true; | |
| 2076 } | |
| 2077 | |
| 2078 void HistoryBackend::SetFaviconSizes( | |
| 2079 FaviconID icon_id, | |
| 2080 const FaviconSizes& sizes) { | |
| 2081 std::vector<FaviconBitmapIDSize> bitmap_id_size_listing; | |
| 2082 thumbnail_db_->GetFaviconBitmapIDSizeListing(icon_id, | |
| 2083 &bitmap_id_size_listing); | |
| 2084 | |
| 2085 // Remove bitmaps whose pixel size is not contained in |sizes|. | |
| 2086 for (size_t i = 0; i < bitmap_id_size_listing.size(); ++i) { | |
| 2087 const gfx::Size& pixel_size = bitmap_id_size_listing[i].pixel_size; | |
| 2088 if (!sizes.has_size(pixel_size)) | |
| 2089 thumbnail_db_->DeleteFaviconBitmap(bitmap_id_size_listing[i].bitmap_id); | |
| 2090 } | |
| 2091 | |
| 2092 thumbnail_db_->SetFaviconSizes(icon_id, sizes.ToString()); | |
| 2093 } | |
| 2094 | |
| 2095 bool HistoryBackend::GetFaviconsFromDB( | |
| 2096 const GURL& page_url, | |
| 2097 int icon_types, | |
| 2098 FaviconData* favicon_data) { | |
| 2099 DCHECK(favicon_data); | |
| 2100 | |
| 2101 if (!db_.get() || !thumbnail_db_.get()) | |
| 2102 return false; | |
| 2103 | |
| 2104 // Time the query. | |
| 2105 TimeTicks beginning_time = TimeTicks::Now(); | |
| 2106 | |
| 2107 bool no_errors = true; | |
| 2108 std::vector<IconMapping> icon_mappings; | |
| 2109 if (thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_types, | |
| 2110 &icon_mappings)) { | |
| 2111 for (std::vector<IconMapping>::iterator i = icon_mappings.begin(); | |
| 2112 i != icon_mappings.end(); ++i) { | |
| 2113 if (!AddToFaviconData(i->icon_id, favicon_data)) { | |
| 2114 no_errors = false; | |
| 2115 break; | |
| 2116 } | |
| 2117 } | |
| 2118 } | |
| 2119 | |
| 2120 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name | |
| 2121 TimeTicks::Now() - beginning_time); | |
| 2122 return no_errors && !favicon_data->icon_url_sizes.empty(); | |
| 2123 } | |
| 2124 | |
| 2125 bool HistoryBackend::AddToFaviconData(FaviconID favicon_id, | |
| 2126 FaviconData* favicon_data) { | |
| 2127 GURL icon_url; | |
| 2128 IconType icon_type; | |
| 2129 std::string sizes_as_string; | |
| 2130 | |
| 2131 if (!thumbnail_db_->GetFaviconHeader(favicon_id, &icon_url, &icon_type, | |
| 2132 &sizes_as_string)) { | |
| 2133 return false; | |
| 2134 } | |
| 2135 | |
| 2136 favicon_data->known_icon = true; | |
| 2137 if (favicon_data->icon_url_sizes.size() == 0) { | |
|
sky
2012/08/21 20:16:56
!empty
Why does this method care about the icon_u
| |
| 2138 favicon_data->icon_type = icon_type; | |
| 2139 favicon_data->expired = false; | |
| 2140 } else { | |
| 2141 DCHECK_EQ(favicon_data->icon_type, icon_type); | |
| 2142 } | |
| 2143 | |
| 2144 favicon_data->icon_url_sizes[icon_url] = FaviconSizes(sizes_as_string); | |
| 2145 | |
| 2146 std::vector<FaviconBitmap> favicon_bitmaps; | |
| 2147 thumbnail_db_->GetFaviconBitmaps(favicon_id, &favicon_bitmaps); | |
| 2148 for (size_t i = 0; i < favicon_bitmaps.size(); ++i) { | |
| 2149 const FaviconBitmap& favicon_bitmap = favicon_bitmaps[i]; | |
| 2150 FaviconDataElement favicon_element; | |
| 2151 favicon_element.bitmap_data = favicon_bitmap.bitmap_data; | |
| 2152 favicon_element.pixel_size = favicon_bitmap.pixel_size; | |
| 2153 favicon_element.icon_url = icon_url; | |
| 2154 favicon_data->elements.push_back(favicon_element); | |
| 2155 | |
| 2156 // Expired is true if at least one favicon bitmap is expired.ww | |
| 2157 favicon_data->expired |= (Time::Now() - favicon_bitmap.last_updated) > | |
| 2158 TimeDelta::FromDays(kFaviconRefetchDays); | |
| 2159 } | |
| 2160 | |
| 2161 return true; | |
| 2162 } | |
| 2163 | |
| 2164 void HistoryBackend::SetFaviconMappingsForPageAndRedirects( | |
| 2165 const GURL& page_url, | |
| 2166 IconType icon_type, | |
| 2167 const IconURLFaviconIDMap& icon_url_id_map) { | |
| 1972 if (!thumbnail_db_.get()) | 2168 if (!thumbnail_db_.get()) |
| 1973 return; | 2169 return; |
| 1974 | 2170 |
| 1975 // Find all the pages whose favicons we should set, we want to set it for | 2171 // Find all the pages whose favicons we should set, we want to set it for |
| 1976 // all the pages in the redirect chain if it redirected. | 2172 // all the pages in the redirect chain if it redirected. |
| 1977 history::RedirectList dummy_list; | 2173 history::RedirectList dummy_list; |
| 1978 history::RedirectList* redirects; | 2174 history::RedirectList* redirects; |
| 1979 RedirectCache::iterator iter = recent_redirects_.Get(page_url); | 2175 RedirectCache::iterator iter = recent_redirects_.Get(page_url); |
| 1980 if (iter != recent_redirects_.end()) { | 2176 if (iter != recent_redirects_.end()) { |
| 1981 redirects = &iter->second; | 2177 redirects = &iter->second; |
| 1982 | 2178 |
| 1983 // This redirect chain should have the destination URL as the last item. | 2179 // This redirect chain should have the destination URL as the last item. |
| 1984 DCHECK(!redirects->empty()); | 2180 DCHECK(!redirects->empty()); |
| 1985 DCHECK(redirects->back() == page_url); | 2181 DCHECK(redirects->back() == page_url); |
| 1986 } else { | 2182 } else { |
| 1987 // No redirect chain stored, make up one containing the URL we want to we | 2183 // No redirect chain stored, make up one containing the URL we want to we |
| 1988 // can use the same logic below. | 2184 // can use the same logic below. |
| 1989 dummy_list.push_back(page_url); | 2185 dummy_list.push_back(page_url); |
| 1990 redirects = &dummy_list; | 2186 redirects = &dummy_list; |
| 1991 } | 2187 } |
| 1992 | 2188 |
| 1993 std::set<GURL> favicons_changed; | 2189 std::set<GURL> favicons_changed; |
| 1994 | 2190 |
| 1995 // Save page <-> favicon association. | 2191 // Save page <-> favicon associations. |
| 1996 for (history::RedirectList::const_iterator i(redirects->begin()); | 2192 for (history::RedirectList::const_iterator i(redirects->begin()); |
| 1997 i != redirects->end(); ++i) { | 2193 i != redirects->end(); ++i) { |
| 1998 FaviconID replaced_id; | 2194 if (SetFaviconMappingsForPage(*i, icon_type, icon_url_id_map)) { |
| 1999 if (AddOrUpdateIconMapping(*i, id, icon_type, &replaced_id)) { | |
| 2000 // The page's favicon ID changed. This means that the one we just | |
| 2001 // changed from could have been orphaned, and we need to re-check it. | |
| 2002 // This is not super fast, but this case will get triggered rarely, | |
| 2003 // since normally a page will always map to the same favicon ID. It | |
| 2004 // will mostly happen for favicons we import. | |
| 2005 if (replaced_id && !thumbnail_db_->HasMappingFor(replaced_id)) | |
| 2006 thumbnail_db_->DeleteFavicon(replaced_id); | |
| 2007 | |
| 2008 favicons_changed.insert(*i); | 2195 favicons_changed.insert(*i); |
| 2009 } | 2196 } |
| 2010 } | 2197 } |
| 2011 | 2198 |
| 2012 // Send the notification about the changed favicons. | 2199 // Send the notification about the changed favicons. |
| 2013 FaviconChangeDetails* changed_details = new FaviconChangeDetails; | 2200 FaviconChangeDetails* changed_details = new FaviconChangeDetails; |
| 2014 changed_details->urls.swap(favicons_changed); | 2201 changed_details->urls.swap(favicons_changed); |
| 2015 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, | 2202 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, |
| 2016 changed_details); | 2203 changed_details); |
| 2017 | 2204 |
| 2018 ScheduleCommit(); | 2205 ScheduleCommit(); |
| 2019 } | 2206 } |
| 2020 | 2207 |
| 2021 bool HistoryBackend::AddOrUpdateIconMapping(const GURL& page_url, | 2208 bool HistoryBackend::SetFaviconMappingsForPage( |
| 2022 FaviconID id, | 2209 const GURL& page_url, |
| 2023 IconType icon_type, | 2210 IconType icon_type, |
| 2024 FaviconID* replaced_icon) { | 2211 const IconURLFaviconIDMap& icon_url_id_map) { |
| 2025 *replaced_icon = 0; | 2212 DCHECK_LE(icon_url_id_map.size(), kMaxFaviconsPerPage); |
| 2213 bool mappings_changed = false; | |
| 2214 | |
| 2215 IconURLFaviconIDMap icon_mappings_to_add = icon_url_id_map; | |
| 2216 | |
| 2217 // Two icon types are considered 'equivalent' if | |
| 2218 // a. The two icon types are equal. | |
| 2219 // b. If one of the icon types is ICON_TOUCH and the other is | |
| 2220 // ICON_PRECOMPOSED_TOUCH. | |
| 2221 // | |
| 2222 // For each of the urls in |icon_url_id_map|. | |
| 2223 // a. If one of the icon mappings has the same icon url as the url from | |
| 2224 // |icon_url_id_map|. | |
| 2225 // i. If the matched icon mapping has the same type as the given | |
| 2226 // |icon_type|, the icon mapping was previously created. | |
| 2227 // ii. If the matched icon mapping has an 'equivalent' icon type to the | |
| 2228 // given |icon_type|, update the icon mapping. | |
| 2229 // b. Otherwise, add the icon mapping represented by the url. | |
| 2230 // c. If there are any icon mappings with an icon_url not in | |
| 2231 // |icon_url_id_map| and the mapping type is the same or equivalent to the | |
| 2232 // given |icon_type|, remove the mapping. | |
| 2233 | |
| 2026 std::vector<IconMapping> icon_mappings; | 2234 std::vector<IconMapping> icon_mappings; |
| 2027 if (!thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) { | 2235 thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings); |
| 2028 // There is no mapping add it directly. | |
| 2029 thumbnail_db_->AddIconMapping(page_url, id); | |
| 2030 return true; | |
| 2031 } | |
| 2032 // Iterate all matched icon mappings, | |
| 2033 // a. If the given icon id and matched icon id are same, return. | |
| 2034 // b. If the given icon type and matched icon type are same, but icon id | |
| 2035 // are not, update the IconMapping. | |
| 2036 // c. If the given icon_type and matched icon type are not same, but | |
| 2037 // either of them is ICON_TOUCH or ICON_PRECOMPOSED_TOUCH, update the | |
| 2038 // IconMapping. | |
| 2039 // d. Otherwise add a icon mapping. | |
| 2040 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 2236 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
| 2041 m != icon_mappings.end(); ++m) { | 2237 m != icon_mappings.end(); ++m) { |
| 2042 if (m->icon_id == id) | |
| 2043 // The mapping is already there. | |
| 2044 return false; | |
| 2045 | |
| 2046 if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) || | 2238 if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) || |
| 2047 (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) || | 2239 (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) || |
| 2048 (icon_type == m->icon_type)) { | 2240 (icon_type == m->icon_type)) { |
| 2049 thumbnail_db_->UpdateIconMapping(m->mapping_id, id); | 2241 IconURLFaviconIDMap::iterator it = |
| 2050 *replaced_icon = m->icon_id; | 2242 icon_mappings_to_add.find(m->icon_url); |
| 2051 return true; | 2243 if (it == icon_mappings_to_add.end()) { |
| 2244 thumbnail_db_->DeleteIconMapping(m->mapping_id); | |
| 2245 } else { | |
| 2246 icon_mappings_to_add.erase(it); | |
| 2247 if (icon_type == m->icon_type) { | |
| 2248 // The mapping is already there. | |
| 2249 continue; | |
| 2250 } | |
| 2251 thumbnail_db_->UpdateIconMapping(m->mapping_id, it->second); | |
| 2252 } | |
| 2253 // Removing / updating the icon mapping may have orphaned the associated | |
| 2254 // favicon so we must recheck it. This is not super fast, but this case | |
| 2255 // will get triggered rarely, since normally a page will always map to | |
| 2256 // the same favicon IDs. It will mostly happen for favicons we import. | |
| 2257 if (!thumbnail_db_->HasMappingFor(m->icon_id)) | |
| 2258 thumbnail_db_->DeleteFavicon(m->icon_id); | |
| 2259 | |
| 2260 mappings_changed = true; | |
| 2052 } | 2261 } |
| 2053 } | 2262 } |
| 2054 thumbnail_db_->AddIconMapping(page_url, id); | 2263 |
| 2055 return true; | 2264 for (IconURLFaviconIDMap::iterator it = icon_mappings_to_add.begin(); |
| 2265 it != icon_mappings_to_add.end(); ++it) { | |
| 2266 thumbnail_db_->AddIconMapping(page_url, it->second); | |
| 2267 mappings_changed = true; | |
| 2268 } | |
| 2269 return mappings_changed; | |
| 2056 } | 2270 } |
| 2057 | 2271 |
| 2058 void HistoryBackend::Commit() { | 2272 void HistoryBackend::Commit() { |
| 2059 if (!db_.get()) | 2273 if (!db_.get()) |
| 2060 return; | 2274 return; |
| 2061 | 2275 |
| 2062 // Note that a commit may not actually have been scheduled if a caller | 2276 // Note that a commit may not actually have been scheduled if a caller |
| 2063 // explicitly calls this instead of using ScheduleCommit. Likewise, we | 2277 // explicitly calls this instead of using ScheduleCommit. Likewise, we |
| 2064 // may reset the flag written by a pending commit. But this is OK! It | 2278 // may reset the flag written by a pending commit. But this is OK! It |
| 2065 // will merely cause extra commits (which is kind of the idea). We | 2279 // will merely cause extra commits (which is kind of the idea). We |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2429 | 2643 |
| 2430 return true; | 2644 return true; |
| 2431 } | 2645 } |
| 2432 | 2646 |
| 2433 BookmarkService* HistoryBackend::GetBookmarkService() { | 2647 BookmarkService* HistoryBackend::GetBookmarkService() { |
| 2434 if (bookmark_service_) | 2648 if (bookmark_service_) |
| 2435 bookmark_service_->BlockTillLoaded(); | 2649 bookmark_service_->BlockTillLoaded(); |
| 2436 return bookmark_service_; | 2650 return bookmark_service_; |
| 2437 } | 2651 } |
| 2438 | 2652 |
| 2439 bool HistoryBackend::GetFaviconFromDB( | |
| 2440 const GURL& page_url, | |
| 2441 int icon_types, | |
| 2442 FaviconData* favicon) { | |
| 2443 DCHECK(favicon); | |
| 2444 | |
| 2445 if (!db_.get() || !thumbnail_db_.get()) | |
| 2446 return false; | |
| 2447 | |
| 2448 bool success = false; | |
| 2449 // Time the query. | |
| 2450 TimeTicks beginning_time = TimeTicks::Now(); | |
| 2451 | |
| 2452 std::vector<IconMapping> icon_mappings; | |
| 2453 // Iterate over the known icons looking for one that includes one of the | |
| 2454 // requested types. | |
| 2455 if (thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) { | |
| 2456 for (std::vector<IconMapping>::iterator i = icon_mappings.begin(); | |
| 2457 i != icon_mappings.end(); ++i) { | |
| 2458 if ((i->icon_type & icon_types) && | |
| 2459 GetFaviconFromDB(i->icon_id, favicon)) { | |
| 2460 success = true; | |
| 2461 break; | |
| 2462 } | |
| 2463 } | |
| 2464 } | |
| 2465 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name | |
| 2466 TimeTicks::Now() - beginning_time); | |
| 2467 return success; | |
| 2468 } | |
| 2469 | |
| 2470 bool HistoryBackend::GetFaviconFromDB(FaviconID favicon_id, | |
| 2471 FaviconData* favicon) { | |
| 2472 Time last_updated; | |
| 2473 scoped_refptr<base::RefCountedMemory> data; | |
| 2474 | |
| 2475 if (!thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data, | |
| 2476 &favicon->icon_url, &favicon->icon_type)) | |
| 2477 return false; | |
| 2478 | |
| 2479 favicon->expired = (Time::Now() - last_updated) > | |
| 2480 TimeDelta::FromDays(kFaviconRefetchDays); | |
| 2481 favicon->known_icon = true; | |
| 2482 favicon->image_data = data; | |
| 2483 return true; | |
| 2484 } | |
| 2485 | |
| 2486 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { | 2653 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { |
| 2487 BriefVisitInfo info; | 2654 BriefVisitInfo info; |
| 2488 info.url_id = visit.url_id; | 2655 info.url_id = visit.url_id; |
| 2489 info.time = visit.visit_time; | 2656 info.time = visit.visit_time; |
| 2490 info.transition = visit.transition; | 2657 info.transition = visit.transition; |
| 2491 // If we don't have a delegate yet during setup or shutdown, we will drop | 2658 // If we don't have a delegate yet during setup or shutdown, we will drop |
| 2492 // these notifications. | 2659 // these notifications. |
| 2493 if (delegate_.get()) | 2660 if (delegate_.get()) |
| 2494 delegate_->NotifyVisitDBObserversOnAddVisit(info); | 2661 delegate_->NotifyVisitDBObserversOnAddVisit(info); |
| 2495 } | 2662 } |
| 2496 | 2663 |
| 2497 } // namespace history | 2664 } // namespace history |
| OLD | NEW |