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 1581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1592 const GURL& icon_url, | 1592 const GURL& icon_url, |
1593 favicon_base::IconType icon_type, | 1593 favicon_base::IconType icon_type, |
1594 scoped_refptr<base::RefCountedMemory> bitmap_data, | 1594 scoped_refptr<base::RefCountedMemory> bitmap_data, |
1595 const gfx::Size& pixel_size) { | 1595 const gfx::Size& pixel_size) { |
1596 if (!thumbnail_db_ || !db_) | 1596 if (!thumbnail_db_ || !db_) |
1597 return; | 1597 return; |
1598 | 1598 |
1599 favicon_base::FaviconID favicon_id = | 1599 favicon_base::FaviconID favicon_id = |
1600 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1600 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
1601 | 1601 |
| 1602 bool favicon_created = false; |
1602 if (!favicon_id) { | 1603 if (!favicon_id) { |
1603 // There is no favicon at |icon_url|, create it. | 1604 // There is no favicon at |icon_url|, create it. |
1604 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1605 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
| 1606 favicon_created = true; |
1605 } | 1607 } |
1606 | 1608 |
1607 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; | 1609 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; |
1608 thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); | 1610 thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); |
1609 | 1611 |
1610 // If there is already a favicon bitmap of |pixel_size| at |icon_url|, | 1612 // If there is already a favicon bitmap of |pixel_size| at |icon_url|, |
1611 // replace it. | 1613 // replace it. |
1612 bool bitmap_identical = false; | 1614 bool bitmap_identical = false; |
1613 bool replaced_bitmap = false; | 1615 bool replaced_bitmap = false; |
1614 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { | 1616 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1682 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from | 1684 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from |
1683 // news.google.com | 1685 // news.google.com |
1684 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not | 1686 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not |
1685 // modified. | 1687 // modified. |
1686 | 1688 |
1687 std::vector<IconMapping> icon_mappings; | 1689 std::vector<IconMapping> icon_mappings; |
1688 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); | 1690 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); |
1689 | 1691 |
1690 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| | 1692 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| |
1691 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. | 1693 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. |
| 1694 bool favicon_bitmaps_copied = false; |
1692 for (size_t i = 0; i < icon_mappings.size(); ++i) { | 1695 for (size_t i = 0; i < icon_mappings.size(); ++i) { |
1693 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) | 1696 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) |
1694 break; | 1697 break; |
1695 | 1698 |
1696 if (icon_mappings[i].icon_url == icon_url) | 1699 if (icon_mappings[i].icon_url == icon_url) |
1697 continue; | 1700 continue; |
1698 | 1701 |
1699 std::vector<FaviconBitmap> bitmaps_to_copy; | 1702 std::vector<FaviconBitmap> bitmaps_to_copy; |
1700 thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, | 1703 thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, |
1701 &bitmaps_to_copy); | 1704 &bitmaps_to_copy); |
1702 for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { | 1705 for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { |
1703 // Do not add a favicon bitmap at a pixel size for which there is already | 1706 // Do not add a favicon bitmap at a pixel size for which there is already |
1704 // a favicon bitmap mapped to |icon_url|. The one there is more correct | 1707 // a favicon bitmap mapped to |icon_url|. The one there is more correct |
1705 // and having multiple equally sized favicon bitmaps for |page_url| is | 1708 // and having multiple equally sized favicon bitmaps for |page_url| is |
1706 // ambiguous in terms of GetFaviconsForURL(). | 1709 // ambiguous in terms of GetFaviconsForURL(). |
1707 std::vector<gfx::Size>::iterator it = | 1710 std::vector<gfx::Size>::iterator it = |
1708 std::find(favicon_sizes.begin(), favicon_sizes.end(), | 1711 std::find(favicon_sizes.begin(), favicon_sizes.end(), |
1709 bitmaps_to_copy[j].pixel_size); | 1712 bitmaps_to_copy[j].pixel_size); |
1710 if (it != favicon_sizes.end()) | 1713 if (it != favicon_sizes.end()) |
1711 continue; | 1714 continue; |
1712 | 1715 |
1713 // Add the favicon bitmap as expired as it is not consistent with the | 1716 // Add the favicon bitmap as expired as it is not consistent with the |
1714 // merged in data. | 1717 // merged in data. |
1715 thumbnail_db_->AddFaviconBitmap( | 1718 thumbnail_db_->AddFaviconBitmap( |
1716 favicon_id, bitmaps_to_copy[j].bitmap_data, base::Time(), | 1719 favicon_id, bitmaps_to_copy[j].bitmap_data, base::Time(), |
1717 bitmaps_to_copy[j].pixel_size); | 1720 bitmaps_to_copy[j].pixel_size); |
1718 favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); | 1721 favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); |
| 1722 favicon_bitmaps_copied = true; |
1719 | 1723 |
1720 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) | 1724 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) |
1721 break; | 1725 break; |
1722 } | 1726 } |
1723 } | 1727 } |
1724 | 1728 |
1725 // Update the favicon mappings such that only |icon_url| is mapped to | 1729 // Update the favicon mappings such that only |icon_url| is mapped to |
1726 // |page_url|. | 1730 // |page_url|. |
1727 bool mapping_changed = false; | |
1728 if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { | 1731 if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { |
1729 std::vector<favicon_base::FaviconID> favicon_ids; | 1732 std::vector<favicon_base::FaviconID> favicon_ids; |
1730 favicon_ids.push_back(favicon_id); | 1733 favicon_ids.push_back(favicon_id); |
1731 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); | 1734 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); |
1732 mapping_changed = true; | 1735 SendFaviconChangedNotificationForPageAndRedirects(page_url); |
1733 } | 1736 } |
1734 | 1737 |
1735 if (mapping_changed || !bitmap_identical) | 1738 if (!favicon_created && (!bitmap_identical || favicon_bitmaps_copied)) { |
1736 SendFaviconChangedNotificationForPageAndRedirects(page_url); | 1739 // If there was a favicon at |icon_url| prior to MergeFavicon() being |
| 1740 // called, there may be page URLs which also use the favicon at |icon_url|. |
| 1741 // Notify the UI that the favicon has changed for |icon_url|. |
| 1742 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1743 } |
| 1744 |
1737 ScheduleCommit(); | 1745 ScheduleCommit(); |
1738 } | 1746 } |
1739 | 1747 |
1740 void HistoryBackend::SetFavicons(const GURL& page_url, | 1748 void HistoryBackend::SetFavicons(const GURL& page_url, |
1741 favicon_base::IconType icon_type, | 1749 favicon_base::IconType icon_type, |
1742 const GURL& icon_url, | 1750 const GURL& icon_url, |
1743 const std::vector<SkBitmap>& bitmaps) { | 1751 const std::vector<SkBitmap>& bitmaps) { |
1744 if (!thumbnail_db_ || !db_) | 1752 if (!thumbnail_db_ || !db_) |
1745 return; | 1753 return; |
1746 | 1754 |
1747 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); | 1755 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); |
1748 | 1756 |
1749 // Track whether the method modifies or creates any favicon bitmaps, favicons | |
1750 // or icon mappings. | |
1751 bool data_modified = false; | |
1752 | |
1753 favicon_base::FaviconID icon_id = | 1757 favicon_base::FaviconID icon_id = |
1754 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1758 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
1755 | 1759 |
| 1760 bool favicon_created = false; |
1756 if (!icon_id) { | 1761 if (!icon_id) { |
1757 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1762 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
1758 data_modified = true; | 1763 favicon_created = true; |
1759 } | 1764 } |
1760 | 1765 |
1761 data_modified |= SetFaviconBitmaps(icon_id, bitmaps); | 1766 bool favicon_data_modified = SetFaviconBitmaps(icon_id, bitmaps); |
1762 | 1767 |
1763 std::vector<favicon_base::FaviconID> icon_ids(1u, icon_id); | 1768 std::vector<favicon_base::FaviconID> icon_ids(1u, icon_id); |
1764 data_modified |= | 1769 bool mapping_changed = |
1765 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); | 1770 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); |
1766 | 1771 |
1767 if (data_modified) { | 1772 if (mapping_changed) { |
1768 // Send notification to the UI as an icon mapping, favicon, or favicon | 1773 // Notify the UI that this function changed an icon mapping. |
1769 // bitmap was changed by this function. | |
1770 SendFaviconChangedNotificationForPageAndRedirects(page_url); | 1774 SendFaviconChangedNotificationForPageAndRedirects(page_url); |
1771 } | 1775 } |
| 1776 |
| 1777 if (favicon_data_modified && !favicon_created) { |
| 1778 // If there was a favicon at |icon_url| prior to SetFavicons() being called, |
| 1779 // there may be page URLs which also use the favicon at |icon_url|. Notify |
| 1780 // the UI that the favicon has changed for |icon_url|. |
| 1781 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1782 } |
1772 ScheduleCommit(); | 1783 ScheduleCommit(); |
1773 } | 1784 } |
1774 | 1785 |
1775 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { | 1786 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { |
1776 std::vector<IconMapping> icon_mappings; | 1787 std::vector<IconMapping> icon_mappings; |
1777 | 1788 |
1778 if (!thumbnail_db_ || | 1789 if (!thumbnail_db_ || |
1779 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) | 1790 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) |
1780 return; | 1791 return; |
1781 | 1792 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 // set already. | 1848 // set already. |
1838 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1849 thumbnail_db_->AddIconMapping(*url, favicon_id); |
1839 favicons_changed.insert(*url); | 1850 favicons_changed.insert(*url); |
1840 } | 1851 } |
1841 } | 1852 } |
1842 } | 1853 } |
1843 } | 1854 } |
1844 | 1855 |
1845 if (!favicons_changed.empty()) { | 1856 if (!favicons_changed.empty()) { |
1846 // Send the notification about the changed favicon URLs. | 1857 // Send the notification about the changed favicon URLs. |
1847 NotifyFaviconChanged(favicons_changed); | 1858 NotifyFaviconsChanged(favicons_changed, std::set<GURL>()); |
1848 } | 1859 } |
1849 } | 1860 } |
1850 | 1861 |
1851 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( | 1862 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( |
1852 const GURL* page_url, | 1863 const GURL* page_url, |
1853 const std::vector<GURL>& icon_urls, | 1864 const std::vector<GURL>& icon_urls, |
1854 int icon_types, | 1865 int icon_types, |
1855 const std::vector<int>& desired_sizes, | 1866 const std::vector<int>& desired_sizes, |
1856 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1867 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
1857 // If |page_url| is specified, |icon_types| must be either a single icon | 1868 // If |page_url| is specified, |icon_types| must be either a single icon |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2166 // No known redirects, construct mock redirect chain containing |page_url|. | 2177 // No known redirects, construct mock redirect chain containing |page_url|. |
2167 redirect_list->push_back(page_url); | 2178 redirect_list->push_back(page_url); |
2168 } | 2179 } |
2169 } | 2180 } |
2170 | 2181 |
2171 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( | 2182 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( |
2172 const GURL& page_url) { | 2183 const GURL& page_url) { |
2173 RedirectList redirect_list; | 2184 RedirectList redirect_list; |
2174 GetCachedRecentRedirects(page_url, &redirect_list); | 2185 GetCachedRecentRedirects(page_url, &redirect_list); |
2175 if (!redirect_list.empty()) { | 2186 if (!redirect_list.empty()) { |
2176 std::set<GURL> favicons_changed(redirect_list.begin(), redirect_list.end()); | 2187 std::set<GURL> favicons_changed(redirect_list.begin(), |
2177 NotifyFaviconChanged(favicons_changed); | 2188 redirect_list.end()); |
| 2189 NotifyFaviconsChanged(favicons_changed, std::set<GURL>()); |
2178 } | 2190 } |
2179 } | 2191 } |
2180 | 2192 |
| 2193 void HistoryBackend::SendFaviconChangedNotificationForIconURL( |
| 2194 const GURL& icon_url) { |
| 2195 std::set<GURL> icon_urls; |
| 2196 icon_urls.insert(icon_url); |
| 2197 NotifyFaviconsChanged(std::set<GURL>(), icon_urls); |
| 2198 } |
| 2199 |
2181 void HistoryBackend::Commit() { | 2200 void HistoryBackend::Commit() { |
2182 if (!db_) | 2201 if (!db_) |
2183 return; | 2202 return; |
2184 | 2203 |
2185 #if defined(OS_IOS) | 2204 #if defined(OS_IOS) |
2186 // Attempts to get the application running long enough to commit the database | 2205 // Attempts to get the application running long enough to commit the database |
2187 // transaction if it is currently being backgrounded. | 2206 // transaction if it is currently being backgrounded. |
2188 base::ios::ScopedCriticalAction scoped_critical_action; | 2207 base::ios::ScopedCriticalAction scoped_critical_action; |
2189 #endif | 2208 #endif |
2190 | 2209 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2453 scoped_ptr<HistoryDBTask> task, | 2472 scoped_ptr<HistoryDBTask> task, |
2454 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, | 2473 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, |
2455 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { | 2474 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { |
2456 bool scheduled = !queued_history_db_tasks_.empty(); | 2475 bool scheduled = !queued_history_db_tasks_.empty(); |
2457 queued_history_db_tasks_.push_back( | 2476 queued_history_db_tasks_.push_back( |
2458 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); | 2477 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); |
2459 if (!scheduled) | 2478 if (!scheduled) |
2460 ProcessDBTaskImpl(); | 2479 ProcessDBTaskImpl(); |
2461 } | 2480 } |
2462 | 2481 |
2463 void HistoryBackend::NotifyFaviconChanged(const std::set<GURL>& urls) { | 2482 void HistoryBackend::NotifyFaviconsChanged(const std::set<GURL>& page_urls, |
| 2483 const std::set<GURL>& icon_urls) { |
2464 if (delegate_) | 2484 if (delegate_) |
2465 delegate_->NotifyFaviconChanged(urls); | 2485 delegate_->NotifyFaviconsChanged(page_urls, icon_urls); |
2466 } | 2486 } |
2467 | 2487 |
2468 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, | 2488 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, |
2469 const URLRow& row, | 2489 const URLRow& row, |
2470 const RedirectList& redirects, | 2490 const RedirectList& redirects, |
2471 base::Time visit_time) { | 2491 base::Time visit_time) { |
2472 URLRow url_info(row); | 2492 URLRow url_info(row); |
2473 if (typed_url_syncable_service_.get()) | 2493 if (typed_url_syncable_service_.get()) |
2474 typed_url_syncable_service_->OnUrlVisited(transition, &url_info); | 2494 typed_url_syncable_service_->OnUrlVisited(transition, &url_info); |
2475 | 2495 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2650 return true; | 2670 return true; |
2651 } | 2671 } |
2652 | 2672 |
2653 HistoryClient* HistoryBackend::GetHistoryClient() { | 2673 HistoryClient* HistoryBackend::GetHistoryClient() { |
2654 if (history_client_) | 2674 if (history_client_) |
2655 history_client_->BlockUntilBookmarksLoaded(); | 2675 history_client_->BlockUntilBookmarksLoaded(); |
2656 return history_client_; | 2676 return history_client_; |
2657 } | 2677 } |
2658 | 2678 |
2659 } // namespace history | 2679 } // namespace history |
OLD | NEW |