Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/history/history_backend.h" | 5 #include "chrome/browser/history/history_backend.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 7 #include <list> | 8 #include <list> |
| 8 #include <map> | 9 #include <map> |
| 9 #include <set> | 10 #include <set> |
| 10 #include <vector> | 11 #include <vector> |
| 11 | 12 |
| 12 #include "base/bind.h" | 13 #include "base/bind.h" |
| 13 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 14 #include "base/file_util.h" | 15 #include "base/file_util.h" |
| 15 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/memory/scoped_vector.h" | 17 #include "base/memory/scoped_vector.h" |
| 17 #include "base/message_loop.h" | 18 #include "base/message_loop.h" |
| 18 #include "base/metrics/histogram.h" | 19 #include "base/metrics/histogram.h" |
| 19 #include "base/string_util.h" | 20 #include "base/string_util.h" |
| 20 #include "base/time.h" | 21 #include "base/time.h" |
| 21 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
| 22 #include "chrome/browser/api/bookmarks/bookmark_service.h" | 23 #include "chrome/browser/api/bookmarks/bookmark_service.h" |
| 23 #include "chrome/browser/autocomplete/history_url_provider.h" | 24 #include "chrome/browser/autocomplete/history_url_provider.h" |
| 24 #include "chrome/browser/cancelable_request.h" | 25 #include "chrome/browser/cancelable_request.h" |
| 26 #include "chrome/browser/favicon/select_favicon_frames.h" | |
| 25 #include "chrome/browser/history/history_notifications.h" | 27 #include "chrome/browser/history/history_notifications.h" |
| 26 #include "chrome/browser/history/history_publisher.h" | 28 #include "chrome/browser/history/history_publisher.h" |
| 27 #include "chrome/browser/history/in_memory_history_backend.h" | 29 #include "chrome/browser/history/in_memory_history_backend.h" |
| 28 #include "chrome/browser/history/page_usage_data.h" | 30 #include "chrome/browser/history/page_usage_data.h" |
| 29 #include "chrome/browser/history/top_sites.h" | 31 #include "chrome/browser/history/top_sites.h" |
| 30 #include "chrome/browser/history/visit_filter.h" | 32 #include "chrome/browser/history/visit_filter.h" |
| 31 #include "chrome/common/chrome_constants.h" | 33 #include "chrome/common/chrome_constants.h" |
| 32 #include "chrome/common/chrome_notification_types.h" | 34 #include "chrome/common/chrome_notification_types.h" |
| 33 #include "chrome/common/url_constants.h" | 35 #include "chrome/common/url_constants.h" |
| 34 #include "content/public/browser/download_persistent_store_info.h" | 36 #include "content/public/browser/download_persistent_store_info.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 static const int kSessionCloseTimeWindowSecs = 10; | 89 static const int kSessionCloseTimeWindowSecs = 10; |
| 88 | 90 |
| 89 // The maximum number of items we'll allow in the redirect list before | 91 // The maximum number of items we'll allow in the redirect list before |
| 90 // deleting some. | 92 // deleting some. |
| 91 static const int kMaxRedirectCount = 32; | 93 static const int kMaxRedirectCount = 32; |
| 92 | 94 |
| 93 // The number of days old a history entry can be before it is considered "old" | 95 // The number of days old a history entry can be before it is considered "old" |
| 94 // and is archived. | 96 // and is archived. |
| 95 static const int kArchiveDaysThreshold = 90; | 97 static const int kArchiveDaysThreshold = 90; |
| 96 | 98 |
| 99 // The maximum number of icons URLs per page which can be stored in the | |
| 100 // thumbnail database. | |
| 101 static const size_t kMaxFaviconsPerPage = 8; | |
| 102 | |
| 103 // The maximum number of bitmaps for a single icon URL which can be stored in | |
| 104 // the thumbnail database. | |
| 105 static const size_t kMaxFaviconBitmapsPerIconURL = 8; | |
| 106 | |
| 97 // Converts from PageUsageData to MostVisitedURL. |redirects| is a | 107 // Converts from PageUsageData to MostVisitedURL. |redirects| is a |
| 98 // list of redirects for this URL. Empty list means no redirects. | 108 // list of redirects for this URL. Empty list means no redirects. |
| 99 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, | 109 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, |
| 100 const RedirectList& redirects) { | 110 const RedirectList& redirects) { |
| 101 MostVisitedURL mv; | 111 MostVisitedURL mv; |
| 102 mv.url = page_data.GetURL(); | 112 mv.url = page_data.GetURL(); |
| 103 mv.title = page_data.GetTitle(); | 113 mv.title = page_data.GetTitle(); |
| 104 if (redirects.empty()) { | 114 if (redirects.empty()) { |
| 105 // Redirects must contain at least the target url. | 115 // Redirects must contain at least the target url. |
| 106 mv.redirects.push_back(mv.url); | 116 mv.redirects.push_back(mv.url); |
| (...skipping 1655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1762 URLID url_id; | 1772 URLID url_id; |
| 1763 if ((url_id = db_->GetRowForURL(redirects.back(), NULL))) | 1773 if ((url_id = db_->GetRowForURL(redirects.back(), NULL))) |
| 1764 success = thumbnail_db_->GetPageThumbnail(url_id, data); | 1774 success = thumbnail_db_->GetPageThumbnail(url_id, data); |
| 1765 } | 1775 } |
| 1766 } | 1776 } |
| 1767 } | 1777 } |
| 1768 | 1778 |
| 1769 return success; | 1779 return success; |
| 1770 } | 1780 } |
| 1771 | 1781 |
| 1772 void HistoryBackend::GetFavicon(scoped_refptr<GetFaviconRequest> request, | 1782 void HistoryBackend::GetFavicons( |
| 1773 const GURL& icon_url, | 1783 scoped_refptr<GetFaviconRequest> request, |
| 1774 int icon_types) { | 1784 const std::vector<GURL>& icon_urls, |
| 1775 UpdateFaviconMappingAndFetchImpl(NULL, icon_url, request, icon_types); | 1785 int icon_types, |
| 1786 int desired_size_in_dip, | |
| 1787 const std::vector<ui::ScaleFactor>& desired_scale_factors) { | |
| 1788 UpdateFaviconMappingsAndFetchImpl(request, NULL, icon_urls, icon_types, | |
| 1789 desired_size_in_dip, desired_scale_factors); | |
| 1776 } | 1790 } |
| 1777 | 1791 |
| 1778 void HistoryBackend::UpdateFaviconMappingAndFetch( | 1792 void HistoryBackend::GetFaviconsForURL( |
| 1779 scoped_refptr<GetFaviconRequest> request, | 1793 scoped_refptr<GetFaviconRequest> request, |
| 1780 const GURL& page_url, | 1794 const GURL& page_url, |
| 1781 const GURL& icon_url, | 1795 int icon_types, |
| 1782 IconType icon_type) { | 1796 int desired_size_in_dip, |
| 1783 UpdateFaviconMappingAndFetchImpl(&page_url, icon_url, request, icon_type); | 1797 const std::vector<ui::ScaleFactor>& desired_scale_factors) { |
| 1798 if (request->canceled()) | |
| 1799 return; | |
| 1800 | |
| 1801 std::vector<FaviconBitmapResult> favicon_bitmap_results; | |
| 1802 IconURLSizesMap icon_url_sizes; | |
| 1803 | |
| 1804 // Get results from DB. | |
| 1805 GetFaviconsFromDB(page_url, icon_types, desired_size_in_dip, | |
| 1806 desired_scale_factors, &favicon_bitmap_results, &icon_url_sizes); | |
| 1807 | |
| 1808 request->ForwardResult(request->handle(), favicon_bitmap_results, | |
| 1809 icon_url_sizes); | |
| 1784 } | 1810 } |
| 1785 | 1811 |
| 1786 void HistoryBackend::SetFaviconOutOfDateForPage(const GURL& page_url) { | 1812 void HistoryBackend::GetFaviconForID(scoped_refptr<GetFaviconRequest> request, |
| 1813 FaviconID id, | |
| 1814 int desired_size_in_dip, | |
| 1815 ui::ScaleFactor desired_scale_factor) { | |
| 1816 if (request->canceled()) | |
| 1817 return; | |
| 1818 | |
| 1819 std::vector<FaviconID> candidate_favicon_ids; | |
| 1820 candidate_favicon_ids.push_back(id); | |
| 1821 std::vector<ui::ScaleFactor> desired_scale_factors; | |
| 1822 desired_scale_factors.push_back(desired_scale_factor); | |
| 1823 | |
| 1824 // Get results from DB. | |
| 1825 std::vector<FaviconBitmapResult> favicon_bitmap_results; | |
| 1826 GetFaviconBitmapResultsForBestMatch(candidate_favicon_ids, | |
| 1827 desired_size_in_dip, desired_scale_factors, &favicon_bitmap_results); | |
| 1828 | |
| 1829 IconURLSizesMap icon_url_sizes; | |
| 1830 BuildIconURLSizesMap(candidate_favicon_ids, &icon_url_sizes); | |
| 1831 | |
| 1832 request->ForwardResult(request->handle(), favicon_bitmap_results, | |
| 1833 icon_url_sizes); | |
| 1834 } | |
| 1835 | |
| 1836 void HistoryBackend::UpdateFaviconMappingsAndFetch( | |
| 1837 scoped_refptr<GetFaviconRequest> request, | |
| 1838 const GURL& page_url, | |
| 1839 const std::vector<GURL>& icon_urls, | |
| 1840 int icon_types, | |
| 1841 int desired_size_in_dip, | |
| 1842 const std::vector<ui::ScaleFactor>& desired_scale_factors) { | |
| 1843 UpdateFaviconMappingsAndFetchImpl(request, &page_url, icon_urls, icon_types, | |
| 1844 desired_size_in_dip, desired_scale_factors); | |
| 1845 } | |
| 1846 | |
| 1847 void HistoryBackend::MergeFavicon( | |
| 1848 const GURL& page_url, | |
| 1849 const GURL& icon_url, | |
| 1850 IconType icon_type, | |
| 1851 scoped_refptr<base::RefCountedMemory> bitmap_data, | |
| 1852 const gfx::Size& pixel_size) { | |
| 1853 if (!thumbnail_db_.get() || !db_.get()) | |
| 1854 return; | |
| 1855 | |
| 1856 gfx::Size merge_pixel_size; | |
| 1857 if (!IsMergeValid(page_url, icon_url, icon_type, pixel_size, | |
| 1858 &merge_pixel_size)) { | |
| 1859 return; | |
| 1860 } | |
| 1861 | |
| 1862 FaviconID favicon_id = | |
| 1863 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, NULL); | |
| 1864 if (favicon_id) { | |
| 1865 FaviconBitmapData bitmap_data_element; | |
| 1866 bitmap_data_element.bitmap_data = bitmap_data; | |
| 1867 bitmap_data_element.pixel_size = merge_pixel_size; | |
| 1868 bitmap_data_element.icon_url = icon_url; | |
| 1869 std::vector<FaviconBitmapData> favicon_bitmap_data; | |
| 1870 favicon_bitmap_data.push_back(bitmap_data_element); | |
| 1871 SetFaviconBitmaps(favicon_id, favicon_bitmap_data); | |
| 1872 } else { | |
| 1873 FaviconSizes favicon_sizes; | |
| 1874 favicon_sizes.push_back(merge_pixel_size); | |
|
sky
2012/09/04 20:52:29
How does an empty size end up getting mapped corre
pkotwicz
2012/09/04 22:40:54
I am unsure as to what you are asking
pkotwicz
2012/09/05 22:39:26
I have updated MergeFavicon().
GetDefaultFaviconSi
| |
| 1875 favicon_id = thumbnail_db_->AddFavicon(icon_url, | |
| 1876 icon_type, | |
| 1877 favicon_sizes, | |
| 1878 bitmap_data, | |
| 1879 base::Time::Now(), | |
| 1880 merge_pixel_size); | |
| 1881 IconURLFaviconIDMap icon_url_id_map; | |
| 1882 icon_url_id_map[icon_url] = favicon_id; | |
| 1883 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, | |
| 1884 icon_url_id_map); | |
| 1885 } | |
| 1886 } | |
| 1887 | |
| 1888 void HistoryBackend::SetFavicons( | |
| 1889 const GURL& page_url, | |
| 1890 IconType icon_type, | |
| 1891 const std::vector<FaviconBitmapData>& favicon_bitmap_data, | |
| 1892 const IconURLSizesMap& icon_url_sizes) { | |
| 1893 if (!thumbnail_db_.get() || !db_.get()) | |
| 1894 return; | |
| 1895 | |
| 1896 DCHECK(ValidateSetFaviconsParams(favicon_bitmap_data, icon_url_sizes)); | |
| 1897 | |
| 1898 // Build map of FaviconBitmapResults for each icon url. | |
| 1899 typedef std::map<GURL, std::vector<FaviconBitmapData> > | |
| 1900 BitmapDataByIconURL; | |
| 1901 BitmapDataByIconURL grouped_by_icon_url; | |
| 1902 for (size_t i = 0; i < favicon_bitmap_data.size(); ++i) { | |
| 1903 const GURL& icon_url = favicon_bitmap_data[i].icon_url; | |
| 1904 grouped_by_icon_url[icon_url].push_back(favicon_bitmap_data[i]); | |
| 1905 } | |
| 1906 | |
| 1907 IconURLFaviconIDMap icon_url_id_map; | |
| 1908 for (IconURLSizesMap::const_iterator it = icon_url_sizes.begin(); | |
| 1909 it != icon_url_sizes.end(); ++it) { | |
| 1910 const GURL& icon_url = it->first; | |
| 1911 FaviconID icon_id = | |
| 1912 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, NULL); | |
| 1913 if (icon_id) | |
| 1914 SetFaviconSizes(icon_id, it->second); | |
| 1915 else | |
| 1916 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type, it->second); | |
| 1917 icon_url_id_map[icon_url] = icon_id; | |
| 1918 | |
| 1919 BitmapDataByIconURL::iterator grouped_by_icon_url_it = | |
| 1920 grouped_by_icon_url.find(icon_url); | |
| 1921 if (grouped_by_icon_url_it != grouped_by_icon_url.end()) | |
| 1922 SetFaviconBitmaps(icon_id, grouped_by_icon_url_it->second); | |
| 1923 } | |
| 1924 | |
| 1925 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_url_id_map); | |
| 1926 } | |
| 1927 | |
| 1928 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { | |
| 1787 std::vector<IconMapping> icon_mappings; | 1929 std::vector<IconMapping> icon_mappings; |
| 1788 | 1930 |
| 1789 if (!thumbnail_db_.get() || | 1931 if (!thumbnail_db_.get() || |
| 1790 !thumbnail_db_->GetIconMappingsForPageURL(page_url, | 1932 !thumbnail_db_->GetIconMappingsForPageURL(page_url, |
| 1791 &icon_mappings)) | 1933 &icon_mappings)) |
| 1792 return; | 1934 return; |
| 1793 | 1935 |
| 1794 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 1936 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
| 1795 m != icon_mappings.end(); ++m) { | 1937 m != icon_mappings.end(); ++m) { |
| 1796 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); | 1938 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); |
| 1797 } | 1939 } |
| 1798 ScheduleCommit(); | 1940 ScheduleCommit(); |
| 1799 } | 1941 } |
| 1800 | 1942 |
| 1801 void HistoryBackend::CloneFavicon(const GURL& old_page_url, | 1943 void HistoryBackend::CloneFavicons(const GURL& old_page_url, |
| 1802 const GURL& new_page_url) { | 1944 const GURL& new_page_url) { |
| 1803 if (!thumbnail_db_.get()) | 1945 if (!thumbnail_db_.get()) |
| 1804 return; | 1946 return; |
| 1805 | 1947 |
| 1806 // Prevent cross-domain cloning. | 1948 // Prevent cross-domain cloning. |
| 1807 if (old_page_url.GetOrigin() != new_page_url.GetOrigin()) | 1949 if (old_page_url.GetOrigin() != new_page_url.GetOrigin()) |
| 1808 return; | 1950 return; |
| 1809 | 1951 |
| 1810 thumbnail_db_->CloneIconMappings(old_page_url, new_page_url); | 1952 thumbnail_db_->CloneIconMappings(old_page_url, new_page_url); |
| 1811 ScheduleCommit(); | 1953 ScheduleCommit(); |
| 1812 } | 1954 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1870 | 2012 |
| 1871 if (!favicons_changed.empty()) { | 2013 if (!favicons_changed.empty()) { |
| 1872 // Send the notification about the changed favicon URLs. | 2014 // Send the notification about the changed favicon URLs. |
| 1873 FaviconChangeDetails* changed_details = new FaviconChangeDetails; | 2015 FaviconChangeDetails* changed_details = new FaviconChangeDetails; |
| 1874 changed_details->urls.swap(favicons_changed); | 2016 changed_details->urls.swap(favicons_changed); |
| 1875 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, | 2017 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, |
| 1876 changed_details); | 2018 changed_details); |
| 1877 } | 2019 } |
| 1878 } | 2020 } |
| 1879 | 2021 |
| 1880 void HistoryBackend::UpdateFaviconMappingAndFetchImpl( | 2022 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( |
| 2023 scoped_refptr<GetFaviconRequest> request, | |
| 1881 const GURL* page_url, | 2024 const GURL* page_url, |
| 1882 const GURL& icon_url, | 2025 const std::vector<GURL>& icon_urls, |
| 1883 scoped_refptr<GetFaviconRequest> request, | 2026 int icon_types, |
| 1884 int icon_types) { | 2027 int desired_size_in_dip, |
| 1885 // Check only a single type was given when the page_url was specified. | 2028 const std::vector<ui::ScaleFactor>& desired_scale_factors) { |
| 1886 DCHECK(!page_url || (page_url && (icon_types == FAVICON || | 2029 // |icon_types| must be either a single icon type or icon types which are |
| 1887 icon_types == TOUCH_ICON || icon_types == TOUCH_PRECOMPOSED_ICON))); | 2030 // equivalent. |
| 1888 | 2031 DCHECK(icon_types == FAVICON || |
| 1889 if (request->canceled()) | 2032 icon_types == TOUCH_ICON || |
| 2033 icon_types == TOUCH_PRECOMPOSED_ICON || | |
| 2034 icon_types == (TOUCH_ICON | TOUCH_PRECOMPOSED_ICON)); | |
| 2035 | |
| 2036 if (request->canceled() || !thumbnail_db_.get()) | |
| 1890 return; | 2037 return; |
| 1891 | 2038 |
| 1892 std::vector<history::FaviconBitmapResult> favicon_bitmap_results; | 2039 std::vector<FaviconID> favicon_ids; |
| 1893 | 2040 IconURLFaviconIDMap icon_url_id_map; |
| 1894 if (thumbnail_db_.get()) { | 2041 |
| 1895 IconType icon_type; | 2042 // The icon type for which the mappings will the updated and data will be |
| 1896 const FaviconID favicon_id = | 2043 // returned. |
| 1897 thumbnail_db_->GetFaviconIDForFaviconURL( | 2044 IconType selected_icon_type = INVALID_ICON; |
| 1898 icon_url, icon_types, &icon_type); | 2045 |
| 2046 for (size_t i = 0; i < icon_urls.size(); ++i) { | |
| 2047 const GURL& icon_url = icon_urls[i]; | |
| 2048 IconType icon_type_out; | |
| 2049 const FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL( | |
| 2050 icon_url, icon_types, &icon_type_out); | |
| 2051 | |
| 1899 if (favicon_id) { | 2052 if (favicon_id) { |
| 1900 GetFaviconFromDB(favicon_id, &favicon_bitmap_results); | 2053 if (icon_type_out > selected_icon_type) { |
|
sky
2012/09/05 00:15:51
This is subtle enough that you should add a commen
| |
| 1901 | 2054 selected_icon_type = icon_type_out; |
| 1902 if (page_url) | 2055 favicon_ids.clear(); |
| 1903 SetFaviconMapping(*page_url, favicon_id, icon_type); | 2056 icon_url_id_map.clear(); |
| 2057 } | |
| 2058 if (icon_type_out == selected_icon_type) { | |
| 2059 favicon_ids.push_back(favicon_id); | |
|
sky
2012/09/04 20:52:29
It feels cumbersome to have to index into icon_url
pkotwicz
2012/09/05 22:39:26
Replaced this with a std::vector<FaviconID>
| |
| 2060 icon_url_id_map[icon_url] = favicon_id; | |
| 2061 } | |
| 1904 } | 2062 } |
| 1905 // else case, haven't cached entry yet. Caller is responsible for | 2063 // else case, haven't cached entry yet. Caller is responsible for |
|
sky
2012/09/04 20:52:29
This comment doesn't really match anymore. Nuke it
| |
| 1906 // downloading the favicon and invoking SetFavicon. | 2064 // downloading the favicon and invoking SetFavicons. |
| 1907 } | 2065 } |
| 1908 // TODO(pkotwicz): Pass map of |icon_url| to the sizes available from the web | 2066 |
| 1909 // at |icon_url| instead of an empty map. | 2067 if (page_url) { |
| 2068 SetFaviconMappingsForPageAndRedirects(*page_url, selected_icon_type, | |
| 2069 icon_url_id_map); | |
| 2070 } | |
| 2071 | |
| 2072 std::vector<FaviconBitmapResult> favicon_bitmap_results; | |
| 2073 IconURLSizesMap icon_url_sizes; | |
| 2074 GetFaviconBitmapResultsForBestMatch(favicon_ids, desired_size_in_dip, | |
| 2075 desired_scale_factors, &favicon_bitmap_results); | |
| 2076 BuildIconURLSizesMap(favicon_ids, &icon_url_sizes); | |
| 2077 | |
| 1910 request->ForwardResult(request->handle(), favicon_bitmap_results, | 2078 request->ForwardResult(request->handle(), favicon_bitmap_results, |
| 1911 IconURLSizesMap()); | 2079 icon_url_sizes); |
| 1912 } | 2080 } |
| 1913 | 2081 |
| 1914 void HistoryBackend::GetFaviconForURL( | 2082 bool HistoryBackend::IsMergeValid(const GURL& page_url, |
| 1915 scoped_refptr<GetFaviconRequest> request, | 2083 const GURL& icon_url, |
| 2084 IconType icon_type, | |
| 2085 const gfx::Size& pixel_size, | |
| 2086 gfx::Size* merge_pixel_size) { | |
| 2087 // Get FaviconIDs for |page_url| and |icon_type|. | |
| 2088 std::vector<IconMapping> icon_mappings; | |
| 2089 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, | |
| 2090 &icon_mappings); | |
| 2091 | |
| 2092 if (!icon_mappings.empty()) { | |
| 2093 // There are already mappings for |page_url|. The merge is invalid if | |
| 2094 // |icon_url| is not part of the mappings. | |
| 2095 bool found_icon_url = false; | |
| 2096 for (size_t i = 0; i < icon_mappings.size(); ++i) { | |
| 2097 if (icon_mappings[i].icon_url == icon_url) { | |
| 2098 found_icon_url = true; | |
| 2099 break; | |
| 2100 } | |
| 2101 } | |
| 2102 if (!found_icon_url) | |
| 2103 return false; | |
| 2104 } | |
| 2105 | |
| 2106 FaviconID favicon_id = | |
| 2107 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, NULL); | |
| 2108 | |
| 2109 if (favicon_id) { | |
| 2110 FaviconSizes favicon_sizes; | |
| 2111 thumbnail_db_->GetFaviconHeader(favicon_id, NULL, NULL, &favicon_sizes); | |
| 2112 | |
| 2113 // The merge is valid if the favicon sizes for |favicon_id| are unkown. | |
|
sky
2012/09/04 20:52:29
unknown
| |
| 2114 if (favicon_sizes == GetDefaultFaviconSizes()) { | |
| 2115 *merge_pixel_size = gfx::Size(); | |
| 2116 return true; | |
| 2117 } | |
| 2118 | |
| 2119 // The merge is invalid if |pixel_size| is not a subset of the favicon | |
| 2120 // sizes of |favicon_id|. | |
| 2121 FaviconSizes::iterator favicon_sizes_it = std::find(favicon_sizes.begin(), | |
| 2122 favicon_sizes.end(), pixel_size); | |
| 2123 if (favicon_sizes_it == favicon_sizes.end()) | |
| 2124 return false; | |
| 2125 | |
| 2126 *merge_pixel_size = *favicon_sizes_it; | |
| 2127 return true; | |
| 2128 } | |
| 2129 | |
| 2130 // The merge is valid if the database knows neither |page_url| or |icon_url|. | |
| 2131 // Use GetDefaultFaviconSizes() as the complete set of favicon sizes the | |
| 2132 // favicon is available from the web are unknown. | |
| 2133 *merge_pixel_size = gfx::Size(); | |
| 2134 return true; | |
| 2135 } | |
| 2136 | |
| 2137 void HistoryBackend::SetFaviconBitmaps( | |
| 2138 FaviconID icon_id, | |
| 2139 const std::vector<FaviconBitmapData>& favicon_bitmap_data) { | |
| 2140 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; | |
| 2141 thumbnail_db_->GetFaviconBitmapIDSizes(icon_id, &bitmap_id_sizes); | |
| 2142 | |
| 2143 // A nested loop is ok because in practice neither |favicon_bitmap_data| nor | |
| 2144 // |bitmap_id_sizes| will have many elements. | |
| 2145 for (size_t i = 0; i < favicon_bitmap_data.size(); ++i) { | |
| 2146 const FaviconBitmapData& bitmap_data_element = favicon_bitmap_data[i]; | |
| 2147 FaviconBitmapID bitmap_id = 0; | |
| 2148 for (size_t j = 0; j < bitmap_id_sizes.size(); ++j) { | |
| 2149 if (bitmap_id_sizes[j].pixel_size == bitmap_data_element.pixel_size) { | |
| 2150 bitmap_id = bitmap_id_sizes[j].bitmap_id; | |
| 2151 break; | |
| 2152 } | |
| 2153 } | |
| 2154 if (bitmap_id) { | |
| 2155 thumbnail_db_->SetFaviconBitmap(bitmap_id, | |
| 2156 bitmap_data_element.bitmap_data, base::Time::Now()); | |
| 2157 } else { | |
| 2158 thumbnail_db_->AddFaviconBitmap(icon_id, bitmap_data_element.bitmap_data, | |
| 2159 base::Time::Now(), bitmap_data_element.pixel_size); | |
| 2160 } | |
| 2161 } | |
| 2162 } | |
| 2163 | |
| 2164 bool HistoryBackend::ValidateSetFaviconsParams( | |
| 2165 const std::vector<FaviconBitmapData>& favicon_bitmap_data, | |
| 2166 const IconURLSizesMap& icon_url_sizes) const { | |
| 2167 if (icon_url_sizes.size() > kMaxFaviconsPerPage) | |
| 2168 return false; | |
| 2169 | |
| 2170 for (IconURLSizesMap::const_iterator it = icon_url_sizes.begin(); | |
| 2171 it != icon_url_sizes.end(); ++it) { | |
| 2172 if (it->second.size() > kMaxFaviconBitmapsPerIconURL) | |
| 2173 return false; | |
| 2174 } | |
| 2175 | |
| 2176 for (size_t i = 0; i < favicon_bitmap_data.size(); ++i) { | |
| 2177 if (!favicon_bitmap_data[i].bitmap_data.get()) | |
| 2178 return false; | |
| 2179 | |
| 2180 IconURLSizesMap::const_iterator it = | |
| 2181 icon_url_sizes.find(favicon_bitmap_data[i].icon_url); | |
| 2182 if (it == icon_url_sizes.end()) | |
| 2183 return false; | |
| 2184 | |
| 2185 const FaviconSizes& favicon_sizes = it->second; | |
| 2186 FaviconSizes::const_iterator it2 = std::find(favicon_sizes.begin(), | |
| 2187 favicon_sizes.end(), favicon_bitmap_data[i].pixel_size); | |
| 2188 if (it2 == favicon_sizes.end()) | |
| 2189 return false; | |
| 2190 } | |
| 2191 return true; | |
| 2192 } | |
| 2193 | |
| 2194 void HistoryBackend::SetFaviconSizes( | |
| 2195 FaviconID icon_id, | |
| 2196 const FaviconSizes& favicon_sizes) { | |
| 2197 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; | |
| 2198 thumbnail_db_->GetFaviconBitmapIDSizes(icon_id, &bitmap_id_sizes); | |
| 2199 | |
| 2200 // Remove bitmaps whose pixel size is not contained in |favicon_sizes|. | |
| 2201 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { | |
| 2202 const gfx::Size& pixel_size = bitmap_id_sizes[i].pixel_size; | |
| 2203 FaviconSizes::const_iterator sizes_it = std::find(favicon_sizes.begin(), | |
| 2204 favicon_sizes.end(), pixel_size); | |
| 2205 if (sizes_it == favicon_sizes.end()) | |
| 2206 thumbnail_db_->DeleteFaviconBitmap(bitmap_id_sizes[i].bitmap_id); | |
| 2207 } | |
| 2208 | |
| 2209 thumbnail_db_->SetFaviconSizes(icon_id, favicon_sizes); | |
| 2210 } | |
| 2211 | |
| 2212 bool HistoryBackend::GetFaviconsFromDB( | |
| 1916 const GURL& page_url, | 2213 const GURL& page_url, |
| 1917 int icon_types) { | 2214 int icon_types, |
| 1918 if (request->canceled()) | 2215 int desired_size_in_dip, |
| 1919 return; | 2216 const std::vector<ui::ScaleFactor>& desired_scale_factors, |
| 1920 | 2217 std::vector<FaviconBitmapResult>* favicon_bitmap_results, |
| 1921 std::vector<FaviconBitmapResult> favicon_bitmap_results; | 2218 IconURLSizesMap* icon_url_sizes) { |
| 1922 | 2219 DCHECK(favicon_bitmap_results); |
| 1923 // Get the favicon from DB. | 2220 DCHECK(icon_url_sizes); |
| 1924 GetFaviconFromDB(page_url, icon_types, &favicon_bitmap_results); | 2221 |
| 1925 | 2222 if (!db_.get() || !thumbnail_db_.get()) |
| 1926 // TODO(pkotwicz): Pass map of matched icon URLs for |icon_types| to the | 2223 return false; |
| 1927 // sizes that each icon URL is available at from the web instead of an | 2224 |
| 1928 // empty map. | 2225 // Time the query. |
| 1929 request->ForwardResult(request->handle(), favicon_bitmap_results, | 2226 TimeTicks beginning_time = TimeTicks::Now(); |
| 1930 IconURLSizesMap()); | 2227 |
| 1931 } | 2228 // Get FaviconIDs for |page_url| and one of |icon_types|. |
| 1932 | 2229 std::vector<IconMapping> icon_mappings; |
| 1933 void HistoryBackend::GetFaviconForID(scoped_refptr<GetFaviconRequest> request, | 2230 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_types, |
| 1934 FaviconID id) { | 2231 &icon_mappings); |
| 1935 if (request->canceled()) | 2232 std::vector<FaviconID> favicon_ids; |
| 1936 return; | 2233 for (size_t i = 0; i < icon_mappings.size(); ++i) |
| 1937 | 2234 favicon_ids.push_back(icon_mappings[i].icon_id); |
| 1938 std::vector<FaviconBitmapResult> favicon_bitmap_results; | 2235 |
| 1939 | 2236 // Populate |favicon_bitmap_results| and |icon_url_sizes|. |
| 1940 // Get the favicon from DB. | 2237 bool success = |
| 1941 GetFaviconFromDB(id, &favicon_bitmap_results); | 2238 GetFaviconBitmapResultsForBestMatch(favicon_ids, |
| 1942 | 2239 desired_size_in_dip, desired_scale_factors, favicon_bitmap_results) && |
| 1943 // TODO(pkotwicz): Pass map of the matched icon URL to the sizes that it is | 2240 BuildIconURLSizesMap(favicon_ids, icon_url_sizes); |
| 1944 // available from the web instead of an empty map. | 2241 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name |
| 1945 request->ForwardResult(request->handle(), favicon_bitmap_results, | 2242 TimeTicks::Now() - beginning_time); |
| 1946 IconURLSizesMap()); | 2243 return success && !icon_url_sizes->empty(); |
| 1947 } | 2244 } |
| 1948 | 2245 |
| 1949 void HistoryBackend::SetFavicon( | 2246 bool HistoryBackend::GetFaviconBitmapResultsForBestMatch( |
| 2247 const std::vector<FaviconID>& candidate_favicon_ids, | |
| 2248 int desired_size_in_dip, | |
| 2249 const std::vector<ui::ScaleFactor>& desired_scale_factors, | |
| 2250 std::vector<history::FaviconBitmapResult>* favicon_bitmap_results) { | |
| 2251 if (candidate_favicon_ids.empty()) | |
| 2252 return false; | |
| 2253 | |
| 2254 // Find the FaviconID and the FaviconBitmapIDs which best match | |
| 2255 // |desired_size_in_dip| and |desired_scale_factors|. | |
| 2256 // TODO(pkotwicz): Select bitmap results from multiple favicons once | |
| 2257 // content::FaviconStatus supports multiple icon URLs. | |
| 2258 FaviconID best_favicon_id = 0; | |
| 2259 std::vector<FaviconBitmapID> best_bitmap_ids; | |
| 2260 // Set |highest_score| less than min valid score of 0. | |
| 2261 float highest_score = -1.0f; | |
|
sky
2012/09/04 20:52:29
nit: add a kInvalidScore some where and use it her
| |
| 2262 for (size_t i = 0; i < candidate_favicon_ids.size(); ++i) { | |
| 2263 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; | |
| 2264 thumbnail_db_->GetFaviconBitmapIDSizes(candidate_favicon_ids[i], | |
| 2265 &bitmap_id_sizes); | |
| 2266 | |
| 2267 std::vector<FaviconBitmapID> candidate_bitmap_ids; | |
| 2268 float score; | |
| 2269 SelectFaviconBitmapIDs(bitmap_id_sizes, | |
| 2270 desired_scale_factors, | |
| 2271 desired_size_in_dip, | |
| 2272 &candidate_bitmap_ids, | |
| 2273 &score); | |
| 2274 if (score > highest_score) { | |
| 2275 best_favicon_id = candidate_favicon_ids[i], | |
|
sky
2012/09/04 20:52:29
does this compile?
pkotwicz
2012/09/05 22:39:26
Done.
| |
| 2276 best_bitmap_ids.swap(candidate_bitmap_ids); | |
| 2277 highest_score = score; | |
| 2278 } | |
| 2279 } | |
| 2280 | |
| 2281 // Construct FaviconBitmapResults from |best_favicon_id| and | |
| 2282 // |best_bitmap_ids|. | |
| 2283 GURL icon_url; | |
| 2284 IconType icon_type; | |
| 2285 if (!thumbnail_db_->GetFaviconHeader(best_favicon_id, &icon_url, | |
| 2286 &icon_type, NULL)) { | |
| 2287 return false; | |
| 2288 } | |
| 2289 | |
| 2290 favicon_bitmap_results->clear(); | |
|
sky
2012/09/04 20:52:29
Shouldn't this be early on in the function?
pkotwicz
2012/09/05 22:39:26
Done.
| |
| 2291 for (size_t i = 0; i < best_bitmap_ids.size(); ++i) { | |
| 2292 base::Time last_updated; | |
| 2293 FaviconBitmapResult bitmap_result; | |
| 2294 bitmap_result.icon_url = icon_url; | |
| 2295 bitmap_result.icon_type = icon_type; | |
| 2296 if (!thumbnail_db_->GetFaviconBitmap(best_bitmap_ids[i], | |
| 2297 &last_updated, | |
| 2298 &bitmap_result.bitmap_data, | |
| 2299 &bitmap_result.pixel_size)) { | |
| 2300 return false; | |
| 2301 } | |
| 2302 | |
| 2303 bitmap_result.expired = (Time::Now() - last_updated) > | |
| 2304 TimeDelta::FromDays(kFaviconRefetchDays); | |
| 2305 if (bitmap_result.is_valid()) | |
| 2306 favicon_bitmap_results->push_back(bitmap_result); | |
| 2307 } | |
| 2308 return true; | |
| 2309 } | |
| 2310 | |
| 2311 bool HistoryBackend::BuildIconURLSizesMap( | |
| 2312 const std::vector<FaviconID>& favicon_ids, | |
| 2313 IconURLSizesMap* icon_url_sizes) { | |
| 2314 icon_url_sizes->clear(); | |
| 2315 for (size_t i = 0; i < favicon_ids.size(); ++i) { | |
| 2316 GURL icon_url; | |
| 2317 FaviconSizes favicon_sizes; | |
| 2318 if (!thumbnail_db_->GetFaviconHeader(favicon_ids[i], &icon_url, NULL, | |
| 2319 &favicon_sizes)) { | |
| 2320 return false; | |
| 2321 } | |
| 2322 (*icon_url_sizes)[icon_url] = favicon_sizes; | |
| 2323 } | |
| 2324 return true; | |
| 2325 } | |
| 2326 | |
| 2327 void HistoryBackend::SetFaviconMappingsForPageAndRedirects( | |
| 1950 const GURL& page_url, | 2328 const GURL& page_url, |
| 1951 const GURL& icon_url, | 2329 IconType icon_type, |
| 1952 scoped_refptr<base::RefCountedMemory> data, | 2330 const IconURLFaviconIDMap& icon_url_id_map) { |
| 1953 IconType icon_type) { | |
| 1954 DCHECK(data.get()); | |
| 1955 if (!thumbnail_db_.get() || !db_.get()) | |
| 1956 return; | |
| 1957 | |
| 1958 FaviconID id = thumbnail_db_->GetFaviconIDForFaviconURL( | |
| 1959 icon_url, icon_type, NULL); | |
| 1960 if (!id) { | |
| 1961 id = thumbnail_db_->AddFavicon(icon_url, | |
| 1962 icon_type, | |
| 1963 GetDefaultFaviconSizes(), | |
| 1964 data, | |
| 1965 Time::Now(), | |
| 1966 gfx::Size()); | |
| 1967 } else { | |
| 1968 thumbnail_db_->DeleteFaviconBitmapsForFavicon(id); | |
| 1969 thumbnail_db_->AddFaviconBitmap(id, data, Time::Now(), gfx::Size()); | |
| 1970 } | |
| 1971 | |
| 1972 SetFaviconMapping(page_url, id, icon_type); | |
| 1973 } | |
| 1974 | |
| 1975 void HistoryBackend::SetFaviconMapping(const GURL& page_url, | |
| 1976 FaviconID id, | |
| 1977 IconType icon_type) { | |
| 1978 if (!thumbnail_db_.get()) | 2331 if (!thumbnail_db_.get()) |
| 1979 return; | 2332 return; |
| 1980 | 2333 |
| 1981 // Find all the pages whose favicons we should set, we want to set it for | 2334 // Find all the pages whose favicons we should set, we want to set it for |
| 1982 // all the pages in the redirect chain if it redirected. | 2335 // all the pages in the redirect chain if it redirected. |
| 1983 history::RedirectList dummy_list; | 2336 history::RedirectList dummy_list; |
| 1984 history::RedirectList* redirects; | 2337 history::RedirectList* redirects; |
| 1985 RedirectCache::iterator iter = recent_redirects_.Get(page_url); | 2338 RedirectCache::iterator iter = recent_redirects_.Get(page_url); |
| 1986 if (iter != recent_redirects_.end()) { | 2339 if (iter != recent_redirects_.end()) { |
| 1987 redirects = &iter->second; | 2340 redirects = &iter->second; |
| 1988 | 2341 |
| 1989 // This redirect chain should have the destination URL as the last item. | 2342 // This redirect chain should have the destination URL as the last item. |
| 1990 DCHECK(!redirects->empty()); | 2343 DCHECK(!redirects->empty()); |
| 1991 DCHECK(redirects->back() == page_url); | 2344 DCHECK(redirects->back() == page_url); |
| 1992 } else { | 2345 } else { |
| 1993 // No redirect chain stored, make up one containing the URL we want to we | 2346 // No redirect chain stored, make up one containing the URL we want to we |
| 1994 // can use the same logic below. | 2347 // can use the same logic below. |
| 1995 dummy_list.push_back(page_url); | 2348 dummy_list.push_back(page_url); |
| 1996 redirects = &dummy_list; | 2349 redirects = &dummy_list; |
| 1997 } | 2350 } |
| 1998 | 2351 |
| 1999 std::set<GURL> favicons_changed; | 2352 std::set<GURL> favicons_changed; |
| 2000 | 2353 |
| 2001 // Save page <-> favicon association. | 2354 // Save page <-> favicon associations. |
| 2002 for (history::RedirectList::const_iterator i(redirects->begin()); | 2355 for (history::RedirectList::const_iterator i(redirects->begin()); |
| 2003 i != redirects->end(); ++i) { | 2356 i != redirects->end(); ++i) { |
| 2004 FaviconID replaced_id; | 2357 if (SetFaviconMappingsForPage(*i, icon_type, icon_url_id_map)) { |
| 2005 if (AddOrUpdateIconMapping(*i, id, icon_type, &replaced_id)) { | |
| 2006 // The page's favicon ID changed. This means that the one we just | |
| 2007 // changed from could have been orphaned, and we need to re-check it. | |
| 2008 // This is not super fast, but this case will get triggered rarely, | |
| 2009 // since normally a page will always map to the same favicon ID. It | |
| 2010 // will mostly happen for favicons we import. | |
| 2011 if (replaced_id && !thumbnail_db_->HasMappingFor(replaced_id)) | |
| 2012 thumbnail_db_->DeleteFavicon(replaced_id); | |
| 2013 | |
| 2014 favicons_changed.insert(*i); | 2358 favicons_changed.insert(*i); |
| 2015 } | 2359 } |
| 2016 } | 2360 } |
| 2017 | 2361 |
| 2018 // Send the notification about the changed favicons. | 2362 // Send the notification about the changed favicons. |
| 2019 FaviconChangeDetails* changed_details = new FaviconChangeDetails; | 2363 FaviconChangeDetails* changed_details = new FaviconChangeDetails; |
| 2020 changed_details->urls.swap(favicons_changed); | 2364 changed_details->urls.swap(favicons_changed); |
| 2021 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, | 2365 BroadcastNotifications(chrome::NOTIFICATION_FAVICON_CHANGED, |
| 2022 changed_details); | 2366 changed_details); |
| 2023 | 2367 |
| 2024 ScheduleCommit(); | 2368 ScheduleCommit(); |
| 2025 } | 2369 } |
| 2026 | 2370 |
| 2027 bool HistoryBackend::AddOrUpdateIconMapping(const GURL& page_url, | 2371 bool HistoryBackend::SetFaviconMappingsForPage( |
| 2028 FaviconID id, | 2372 const GURL& page_url, |
| 2029 IconType icon_type, | 2373 IconType icon_type, |
| 2030 FaviconID* replaced_icon) { | 2374 const IconURLFaviconIDMap& icon_url_id_map) { |
| 2031 *replaced_icon = 0; | 2375 DCHECK_LE(icon_url_id_map.size(), kMaxFaviconsPerPage); |
| 2376 bool mappings_changed = false; | |
| 2377 | |
| 2378 // Two icon types are considered 'equivalent' if one of the icon types is | |
| 2379 // ICON_TOUCH and the other is ICON_PRECOMPOSED_TOUCH. | |
| 2380 // | |
| 2381 // Sets the icon mappings of |page_url| for |icon_type| to the icon URLs | |
| 2382 // and favicon ids in |icon_url_id_map|. The mappings from |page_url| for | |
| 2383 // any icon URLs not in |icon_url_id_map| are removed. | |
| 2384 // The icon mappings of |page_url| for equivalent icon types are removed. | |
| 2385 // Remove any favicons which are orphaned as a result of the removal of the | |
| 2386 // icon mappings. | |
| 2387 | |
| 2388 IconURLFaviconIDMap icon_mappings_to_add = icon_url_id_map; | |
| 2389 | |
| 2032 std::vector<IconMapping> icon_mappings; | 2390 std::vector<IconMapping> icon_mappings; |
| 2033 if (!thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) { | 2391 thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings); |
| 2034 // There is no mapping add it directly. | |
| 2035 thumbnail_db_->AddIconMapping(page_url, id); | |
| 2036 return true; | |
| 2037 } | |
| 2038 // Iterate all matched icon mappings, | |
| 2039 // a. If the given icon id and matched icon id are same, return. | |
| 2040 // b. If the given icon type and matched icon type are same, but icon id | |
| 2041 // are not, update the IconMapping. | |
| 2042 // c. If the given icon_type and matched icon type are not same, but | |
| 2043 // either of them is ICON_TOUCH or ICON_PRECOMPOSED_TOUCH, update the | |
| 2044 // IconMapping. | |
| 2045 // d. Otherwise add a icon mapping. | |
| 2046 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 2392 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
| 2047 m != icon_mappings.end(); ++m) { | 2393 m != icon_mappings.end(); ++m) { |
| 2048 if (m->icon_id == id) | 2394 if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) || |
| 2049 // The mapping is already there. | 2395 (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) || |
| 2050 return false; | 2396 icon_type == m->icon_type) { |
| 2397 IconURLFaviconIDMap::iterator it = | |
| 2398 icon_mappings_to_add.find(m->icon_url); | |
| 2399 if (it == icon_mappings_to_add.end()) { | |
| 2400 thumbnail_db_->DeleteIconMapping(m->mapping_id); | |
| 2401 } else { | |
| 2402 FaviconID icon_id = it->second; | |
| 2403 icon_mappings_to_add.erase(it); | |
| 2404 if (icon_id == m->icon_id) { | |
| 2405 // Keep icon mapping. | |
| 2406 continue; | |
| 2407 } | |
| 2051 | 2408 |
| 2052 if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) || | 2409 thumbnail_db_->UpdateIconMapping(m->mapping_id, icon_id); |
| 2053 (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) || | 2410 } |
| 2054 (icon_type == m->icon_type)) { | 2411 // Removing / updating the icon mapping may have orphaned the associated |
| 2055 thumbnail_db_->UpdateIconMapping(m->mapping_id, id); | 2412 // favicon so we must recheck it. This is not super fast, but this case |
| 2056 *replaced_icon = m->icon_id; | 2413 // will get triggered rarely, since normally a page will always map to |
| 2057 return true; | 2414 // the same favicon IDs. It will mostly happen for favicons we import. |
| 2415 if (!thumbnail_db_->HasMappingFor(m->icon_id)) | |
| 2416 thumbnail_db_->DeleteFavicon(m->icon_id); | |
| 2417 mappings_changed = true; | |
| 2058 } | 2418 } |
| 2059 } | 2419 } |
| 2060 thumbnail_db_->AddIconMapping(page_url, id); | 2420 |
| 2061 return true; | 2421 for (IconURLFaviconIDMap::iterator it = icon_mappings_to_add.begin(); |
| 2422 it != icon_mappings_to_add.end(); ++it) { | |
| 2423 thumbnail_db_->AddIconMapping(page_url, it->second); | |
| 2424 mappings_changed = true; | |
| 2425 } | |
| 2426 return mappings_changed; | |
| 2062 } | 2427 } |
| 2063 | 2428 |
| 2064 void HistoryBackend::Commit() { | 2429 void HistoryBackend::Commit() { |
| 2065 if (!db_.get()) | 2430 if (!db_.get()) |
| 2066 return; | 2431 return; |
| 2067 | 2432 |
| 2068 // Note that a commit may not actually have been scheduled if a caller | 2433 // Note that a commit may not actually have been scheduled if a caller |
| 2069 // explicitly calls this instead of using ScheduleCommit. Likewise, we | 2434 // explicitly calls this instead of using ScheduleCommit. Likewise, we |
| 2070 // may reset the flag written by a pending commit. But this is OK! It | 2435 // may reset the flag written by a pending commit. But this is OK! It |
| 2071 // will merely cause extra commits (which is kind of the idea). We | 2436 // 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... | |
| 2435 | 2800 |
| 2436 return true; | 2801 return true; |
| 2437 } | 2802 } |
| 2438 | 2803 |
| 2439 BookmarkService* HistoryBackend::GetBookmarkService() { | 2804 BookmarkService* HistoryBackend::GetBookmarkService() { |
| 2440 if (bookmark_service_) | 2805 if (bookmark_service_) |
| 2441 bookmark_service_->BlockTillLoaded(); | 2806 bookmark_service_->BlockTillLoaded(); |
| 2442 return bookmark_service_; | 2807 return bookmark_service_; |
| 2443 } | 2808 } |
| 2444 | 2809 |
| 2445 bool HistoryBackend::GetFaviconFromDB( | |
| 2446 const GURL& page_url, | |
| 2447 int icon_types, | |
| 2448 std::vector<FaviconBitmapResult>* favicon_bitmap_results) { | |
| 2449 DCHECK(favicon_bitmap_results); | |
| 2450 | |
| 2451 if (!db_.get() || !thumbnail_db_.get()) | |
| 2452 return false; | |
| 2453 | |
| 2454 bool success = false; | |
| 2455 // Time the query. | |
| 2456 TimeTicks beginning_time = TimeTicks::Now(); | |
| 2457 | |
| 2458 std::vector<IconMapping> icon_mappings; | |
| 2459 // Iterate over the known icons looking for one that includes one of the | |
| 2460 // requested types. | |
| 2461 if (thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) { | |
| 2462 for (std::vector<IconMapping>::iterator i = icon_mappings.begin(); | |
| 2463 i != icon_mappings.end(); ++i) { | |
| 2464 if ((i->icon_type & icon_types) && | |
| 2465 GetFaviconFromDB(i->icon_id, favicon_bitmap_results)) { | |
| 2466 success = true; | |
| 2467 break; | |
| 2468 } | |
| 2469 } | |
| 2470 } | |
| 2471 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name | |
| 2472 TimeTicks::Now() - beginning_time); | |
| 2473 return success; | |
| 2474 } | |
| 2475 | |
| 2476 bool HistoryBackend::GetFaviconFromDB( | |
| 2477 FaviconID favicon_id, | |
| 2478 std::vector<history::FaviconBitmapResult>* favicon_bitmap_results) { | |
| 2479 FaviconBitmapResult bitmap_result; | |
| 2480 Time last_updated; | |
| 2481 if (!thumbnail_db_->GetFaviconHeader(favicon_id, | |
| 2482 &bitmap_result.icon_url, | |
| 2483 &bitmap_result.icon_type, | |
| 2484 NULL)) { | |
| 2485 return false; | |
| 2486 } | |
| 2487 | |
| 2488 std::vector<FaviconBitmap> favicon_bitmaps; | |
| 2489 thumbnail_db_->GetFaviconBitmaps(favicon_id, &favicon_bitmaps); | |
| 2490 if (favicon_bitmaps.empty()) | |
| 2491 return false; | |
| 2492 | |
| 2493 bitmap_result.bitmap_data = favicon_bitmaps[0].bitmap_data; | |
| 2494 bitmap_result.expired = (Time::Now() - favicon_bitmaps[0].last_updated) > | |
| 2495 TimeDelta::FromDays(kFaviconRefetchDays); | |
| 2496 | |
| 2497 favicon_bitmap_results->clear(); | |
| 2498 if (bitmap_result.is_valid()) | |
| 2499 favicon_bitmap_results->push_back(bitmap_result); | |
| 2500 return true; | |
| 2501 } | |
| 2502 | |
| 2503 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { | 2810 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { |
| 2504 BriefVisitInfo info; | 2811 BriefVisitInfo info; |
| 2505 info.url_id = visit.url_id; | 2812 info.url_id = visit.url_id; |
| 2506 info.time = visit.visit_time; | 2813 info.time = visit.visit_time; |
| 2507 info.transition = visit.transition; | 2814 info.transition = visit.transition; |
| 2508 // If we don't have a delegate yet during setup or shutdown, we will drop | 2815 // If we don't have a delegate yet during setup or shutdown, we will drop |
| 2509 // these notifications. | 2816 // these notifications. |
| 2510 if (delegate_.get()) | 2817 if (delegate_.get()) |
| 2511 delegate_->NotifyVisitDBObserversOnAddVisit(info); | 2818 delegate_->NotifyVisitDBObserversOnAddVisit(info); |
| 2512 } | 2819 } |
| 2513 | 2820 |
| 2514 } // namespace history | 2821 } // namespace history |
| OLD | NEW |