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 "components/history/core/browser/history_backend.h" | 5 #include "components/history/core/browser/history_backend.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <list> | 9 #include <list> |
10 #include <map> | 10 #include <map> |
(...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1600 const GURL& icon_url, | 1600 const GURL& icon_url, |
1601 favicon_base::IconType icon_type, | 1601 favicon_base::IconType icon_type, |
1602 scoped_refptr<base::RefCountedMemory> bitmap_data, | 1602 scoped_refptr<base::RefCountedMemory> bitmap_data, |
1603 const gfx::Size& pixel_size) { | 1603 const gfx::Size& pixel_size) { |
1604 if (!thumbnail_db_ || !db_) | 1604 if (!thumbnail_db_ || !db_) |
1605 return; | 1605 return; |
1606 | 1606 |
1607 favicon_base::FaviconID favicon_id = | 1607 favicon_base::FaviconID favicon_id = |
1608 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1608 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
1609 | 1609 |
| 1610 bool favicon_created = false; |
1610 if (!favicon_id) { | 1611 if (!favicon_id) { |
1611 // There is no favicon at |icon_url|, create it. | 1612 // There is no favicon at |icon_url|, create it. |
1612 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1613 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
| 1614 favicon_created = true; |
1613 } | 1615 } |
1614 | 1616 |
1615 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; | 1617 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; |
1616 thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); | 1618 thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); |
1617 | 1619 |
1618 // If there is already a favicon bitmap of |pixel_size| at |icon_url|, | 1620 // If there is already a favicon bitmap of |pixel_size| at |icon_url|, |
1619 // replace it. | 1621 // replace it. |
1620 bool bitmap_identical = false; | 1622 bool bitmap_identical = false; |
1621 bool replaced_bitmap = false; | 1623 bool replaced_bitmap = false; |
1622 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { | 1624 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from | 1692 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from |
1691 // news.google.com | 1693 // news.google.com |
1692 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not | 1694 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not |
1693 // modified. | 1695 // modified. |
1694 | 1696 |
1695 std::vector<IconMapping> icon_mappings; | 1697 std::vector<IconMapping> icon_mappings; |
1696 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); | 1698 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); |
1697 | 1699 |
1698 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| | 1700 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| |
1699 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. | 1701 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. |
| 1702 bool favicon_bitmaps_copied = false; |
1700 for (size_t i = 0; i < icon_mappings.size(); ++i) { | 1703 for (size_t i = 0; i < icon_mappings.size(); ++i) { |
1701 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) | 1704 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) |
1702 break; | 1705 break; |
1703 | 1706 |
1704 if (icon_mappings[i].icon_url == icon_url) | 1707 if (icon_mappings[i].icon_url == icon_url) |
1705 continue; | 1708 continue; |
1706 | 1709 |
1707 std::vector<FaviconBitmap> bitmaps_to_copy; | 1710 std::vector<FaviconBitmap> bitmaps_to_copy; |
1708 thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, | 1711 thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, |
1709 &bitmaps_to_copy); | 1712 &bitmaps_to_copy); |
1710 for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { | 1713 for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { |
1711 // Do not add a favicon bitmap at a pixel size for which there is already | 1714 // Do not add a favicon bitmap at a pixel size for which there is already |
1712 // a favicon bitmap mapped to |icon_url|. The one there is more correct | 1715 // a favicon bitmap mapped to |icon_url|. The one there is more correct |
1713 // and having multiple equally sized favicon bitmaps for |page_url| is | 1716 // and having multiple equally sized favicon bitmaps for |page_url| is |
1714 // ambiguous in terms of GetFaviconsForURL(). | 1717 // ambiguous in terms of GetFaviconsForURL(). |
1715 std::vector<gfx::Size>::iterator it = | 1718 std::vector<gfx::Size>::iterator it = |
1716 std::find(favicon_sizes.begin(), favicon_sizes.end(), | 1719 std::find(favicon_sizes.begin(), favicon_sizes.end(), |
1717 bitmaps_to_copy[j].pixel_size); | 1720 bitmaps_to_copy[j].pixel_size); |
1718 if (it != favicon_sizes.end()) | 1721 if (it != favicon_sizes.end()) |
1719 continue; | 1722 continue; |
1720 | 1723 |
1721 // Add the favicon bitmap as expired as it is not consistent with the | 1724 // Add the favicon bitmap as expired as it is not consistent with the |
1722 // merged in data. | 1725 // merged in data. |
1723 thumbnail_db_->AddFaviconBitmap( | 1726 thumbnail_db_->AddFaviconBitmap( |
1724 favicon_id, bitmaps_to_copy[j].bitmap_data, base::Time(), | 1727 favicon_id, bitmaps_to_copy[j].bitmap_data, base::Time(), |
1725 bitmaps_to_copy[j].pixel_size); | 1728 bitmaps_to_copy[j].pixel_size); |
1726 favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); | 1729 favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); |
| 1730 favicon_bitmaps_copied = true; |
1727 | 1731 |
1728 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) | 1732 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) |
1729 break; | 1733 break; |
1730 } | 1734 } |
1731 } | 1735 } |
1732 | 1736 |
1733 // Update the favicon mappings such that only |icon_url| is mapped to | 1737 // Update the favicon mappings such that only |icon_url| is mapped to |
1734 // |page_url|. | 1738 // |page_url|. |
1735 bool mapping_changed = false; | |
1736 if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { | 1739 if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { |
1737 std::vector<favicon_base::FaviconID> favicon_ids; | 1740 std::vector<favicon_base::FaviconID> favicon_ids; |
1738 favicon_ids.push_back(favicon_id); | 1741 favicon_ids.push_back(favicon_id); |
1739 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); | 1742 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); |
1740 mapping_changed = true; | 1743 SendFaviconChangedNotificationForPageAndRedirects(page_url); |
1741 } | 1744 } |
1742 | 1745 |
1743 if (mapping_changed || !bitmap_identical) | 1746 if (!favicon_created && (!bitmap_identical || favicon_bitmaps_copied)) { |
1744 SendFaviconChangedNotificationForPageAndRedirects(page_url); | 1747 // If there was a favicon at |icon_url| prior to MergeFavicon() being |
| 1748 // called, there may be page URLs which also use the favicon at |icon_url|. |
| 1749 // Notify the UI that the favicon has changed for |icon_url|. |
| 1750 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1751 } |
| 1752 |
1745 ScheduleCommit(); | 1753 ScheduleCommit(); |
1746 } | 1754 } |
1747 | 1755 |
1748 void HistoryBackend::SetFavicons(const GURL& page_url, | 1756 void HistoryBackend::SetFavicons(const GURL& page_url, |
1749 favicon_base::IconType icon_type, | 1757 favicon_base::IconType icon_type, |
1750 const GURL& icon_url, | 1758 const GURL& icon_url, |
1751 const std::vector<SkBitmap>& bitmaps) { | 1759 const std::vector<SkBitmap>& bitmaps) { |
1752 if (!thumbnail_db_ || !db_) | 1760 if (!thumbnail_db_ || !db_) |
1753 return; | 1761 return; |
1754 | 1762 |
1755 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); | 1763 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); |
1756 | 1764 |
1757 // Track whether the method modifies or creates any favicon bitmaps, favicons | |
1758 // or icon mappings. | |
1759 bool data_modified = false; | |
1760 | |
1761 favicon_base::FaviconID icon_id = | 1765 favicon_base::FaviconID icon_id = |
1762 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1766 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
1763 | 1767 |
| 1768 bool favicon_created = false; |
1764 if (!icon_id) { | 1769 if (!icon_id) { |
1765 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1770 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
1766 data_modified = true; | 1771 favicon_created = true; |
1767 } | 1772 } |
1768 | 1773 |
1769 data_modified |= SetFaviconBitmaps(icon_id, bitmaps); | 1774 bool favicon_data_modified = SetFaviconBitmaps(icon_id, bitmaps); |
1770 | 1775 |
1771 std::vector<favicon_base::FaviconID> icon_ids(1u, icon_id); | 1776 std::vector<favicon_base::FaviconID> icon_ids(1u, icon_id); |
1772 data_modified |= | 1777 bool mapping_changed = |
1773 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); | 1778 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); |
1774 | 1779 |
1775 if (data_modified) { | 1780 if (mapping_changed) { |
1776 // Send notification to the UI as an icon mapping, favicon, or favicon | 1781 // Notify the UI that this function changed an icon mapping. |
1777 // bitmap was changed by this function. | |
1778 SendFaviconChangedNotificationForPageAndRedirects(page_url); | 1782 SendFaviconChangedNotificationForPageAndRedirects(page_url); |
1779 } | 1783 } |
| 1784 |
| 1785 if (favicon_data_modified && !favicon_created) { |
| 1786 // If there was a favicon at |icon_url| prior to SetFavicons() being called, |
| 1787 // there may be page URLs which also use the favicon at |icon_url|. Notify |
| 1788 // the UI that the favicon has changed for |icon_url|. |
| 1789 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1790 } |
1780 ScheduleCommit(); | 1791 ScheduleCommit(); |
1781 } | 1792 } |
1782 | 1793 |
1783 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { | 1794 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { |
1784 std::vector<IconMapping> icon_mappings; | 1795 std::vector<IconMapping> icon_mappings; |
1785 | 1796 |
1786 if (!thumbnail_db_ || | 1797 if (!thumbnail_db_ || |
1787 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) | 1798 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) |
1788 return; | 1799 return; |
1789 | 1800 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1844 // set already. | 1855 // set already. |
1845 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1856 thumbnail_db_->AddIconMapping(*url, favicon_id); |
1846 favicons_changed.insert(*url); | 1857 favicons_changed.insert(*url); |
1847 } | 1858 } |
1848 } | 1859 } |
1849 } | 1860 } |
1850 } | 1861 } |
1851 | 1862 |
1852 if (!favicons_changed.empty()) { | 1863 if (!favicons_changed.empty()) { |
1853 // Send the notification about the changed favicon URLs. | 1864 // Send the notification about the changed favicon URLs. |
1854 NotifyFaviconChanged(favicons_changed); | 1865 NotifyFaviconsChanged(favicons_changed, GURL()); |
1855 } | 1866 } |
1856 } | 1867 } |
1857 | 1868 |
1858 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( | 1869 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( |
1859 const GURL* page_url, | 1870 const GURL* page_url, |
1860 const std::vector<GURL>& icon_urls, | 1871 const std::vector<GURL>& icon_urls, |
1861 int icon_types, | 1872 int icon_types, |
1862 const std::vector<int>& desired_sizes, | 1873 const std::vector<int>& desired_sizes, |
1863 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1874 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
1864 // If |page_url| is specified, |icon_types| must be either a single icon | 1875 // If |page_url| is specified, |icon_types| must be either a single icon |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2189 // No known redirects, construct mock redirect chain containing |page_url|. | 2200 // No known redirects, construct mock redirect chain containing |page_url|. |
2190 redirect_list->push_back(page_url); | 2201 redirect_list->push_back(page_url); |
2191 } | 2202 } |
2192 } | 2203 } |
2193 | 2204 |
2194 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( | 2205 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( |
2195 const GURL& page_url) { | 2206 const GURL& page_url) { |
2196 RedirectList redirect_list; | 2207 RedirectList redirect_list; |
2197 GetCachedRecentRedirects(page_url, &redirect_list); | 2208 GetCachedRecentRedirects(page_url, &redirect_list); |
2198 if (!redirect_list.empty()) { | 2209 if (!redirect_list.empty()) { |
2199 std::set<GURL> favicons_changed(redirect_list.begin(), redirect_list.end()); | 2210 std::set<GURL> favicons_changed(redirect_list.begin(), |
2200 NotifyFaviconChanged(favicons_changed); | 2211 redirect_list.end()); |
| 2212 NotifyFaviconsChanged(favicons_changed, GURL()); |
2201 } | 2213 } |
2202 } | 2214 } |
2203 | 2215 |
| 2216 void HistoryBackend::SendFaviconChangedNotificationForIconURL( |
| 2217 const GURL& icon_url) { |
| 2218 NotifyFaviconsChanged(std::set<GURL>(), icon_url); |
| 2219 } |
| 2220 |
2204 void HistoryBackend::Commit() { | 2221 void HistoryBackend::Commit() { |
2205 if (!db_) | 2222 if (!db_) |
2206 return; | 2223 return; |
2207 | 2224 |
2208 #if defined(OS_IOS) | 2225 #if defined(OS_IOS) |
2209 // Attempts to get the application running long enough to commit the database | 2226 // Attempts to get the application running long enough to commit the database |
2210 // transaction if it is currently being backgrounded. | 2227 // transaction if it is currently being backgrounded. |
2211 base::ios::ScopedCriticalAction scoped_critical_action; | 2228 base::ios::ScopedCriticalAction scoped_critical_action; |
2212 #endif | 2229 #endif |
2213 | 2230 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2476 scoped_ptr<HistoryDBTask> task, | 2493 scoped_ptr<HistoryDBTask> task, |
2477 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, | 2494 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, |
2478 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { | 2495 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { |
2479 bool scheduled = !queued_history_db_tasks_.empty(); | 2496 bool scheduled = !queued_history_db_tasks_.empty(); |
2480 queued_history_db_tasks_.push_back( | 2497 queued_history_db_tasks_.push_back( |
2481 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); | 2498 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); |
2482 if (!scheduled) | 2499 if (!scheduled) |
2483 ProcessDBTaskImpl(); | 2500 ProcessDBTaskImpl(); |
2484 } | 2501 } |
2485 | 2502 |
2486 void HistoryBackend::NotifyFaviconChanged(const std::set<GURL>& urls) { | 2503 void HistoryBackend::NotifyFaviconsChanged(const std::set<GURL>& page_urls, |
| 2504 const GURL& icon_url) { |
2487 if (delegate_) | 2505 if (delegate_) |
2488 delegate_->NotifyFaviconChanged(urls); | 2506 delegate_->NotifyFaviconsChanged(page_urls, icon_url); |
2489 } | 2507 } |
2490 | 2508 |
2491 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, | 2509 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, |
2492 const URLRow& row, | 2510 const URLRow& row, |
2493 const RedirectList& redirects, | 2511 const RedirectList& redirects, |
2494 base::Time visit_time) { | 2512 base::Time visit_time) { |
2495 URLRow url_info(row); | 2513 URLRow url_info(row); |
2496 if (typed_url_syncable_service_.get()) | 2514 if (typed_url_syncable_service_.get()) |
2497 typed_url_syncable_service_->OnUrlVisited(transition, &url_info); | 2515 typed_url_syncable_service_->OnUrlVisited(transition, &url_info); |
2498 | 2516 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2666 // transaction is currently open. | 2684 // transaction is currently open. |
2667 db_->CommitTransaction(); | 2685 db_->CommitTransaction(); |
2668 db_->Vacuum(); | 2686 db_->Vacuum(); |
2669 db_->BeginTransaction(); | 2687 db_->BeginTransaction(); |
2670 db_->GetStartDate(&first_recorded_time_); | 2688 db_->GetStartDate(&first_recorded_time_); |
2671 | 2689 |
2672 return true; | 2690 return true; |
2673 } | 2691 } |
2674 | 2692 |
2675 } // namespace history | 2693 } // namespace history |
OLD | NEW |