| 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 1612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1623 const GURL& icon_url, | 1623 const GURL& icon_url, |
| 1624 favicon_base::IconType icon_type, | 1624 favicon_base::IconType icon_type, |
| 1625 scoped_refptr<base::RefCountedMemory> bitmap_data, | 1625 scoped_refptr<base::RefCountedMemory> bitmap_data, |
| 1626 const gfx::Size& pixel_size) { | 1626 const gfx::Size& pixel_size) { |
| 1627 if (!thumbnail_db_ || !db_) | 1627 if (!thumbnail_db_ || !db_) |
| 1628 return; | 1628 return; |
| 1629 | 1629 |
| 1630 favicon_base::FaviconID favicon_id = | 1630 favicon_base::FaviconID favicon_id = |
| 1631 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1631 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
| 1632 | 1632 |
| 1633 bool favicon_created = false; |
| 1633 if (!favicon_id) { | 1634 if (!favicon_id) { |
| 1634 // There is no favicon at |icon_url|, create it. | 1635 // There is no favicon at |icon_url|, create it. |
| 1635 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1636 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
| 1637 favicon_created = true; |
| 1636 } | 1638 } |
| 1637 | 1639 |
| 1638 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; | 1640 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; |
| 1639 thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); | 1641 thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); |
| 1640 | 1642 |
| 1641 // If there is already a favicon bitmap of |pixel_size| at |icon_url|, | 1643 // If there is already a favicon bitmap of |pixel_size| at |icon_url|, |
| 1642 // replace it. | 1644 // replace it. |
| 1643 bool bitmap_identical = false; | 1645 bool bitmap_identical = false; |
| 1644 bool replaced_bitmap = false; | 1646 bool replaced_bitmap = false; |
| 1645 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { | 1647 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from | 1715 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from |
| 1714 // news.google.com | 1716 // news.google.com |
| 1715 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not | 1717 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not |
| 1716 // modified. | 1718 // modified. |
| 1717 | 1719 |
| 1718 std::vector<IconMapping> icon_mappings; | 1720 std::vector<IconMapping> icon_mappings; |
| 1719 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); | 1721 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); |
| 1720 | 1722 |
| 1721 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| | 1723 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| |
| 1722 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. | 1724 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. |
| 1725 bool favicon_bitmaps_copied = false; |
| 1723 for (size_t i = 0; i < icon_mappings.size(); ++i) { | 1726 for (size_t i = 0; i < icon_mappings.size(); ++i) { |
| 1724 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) | 1727 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) |
| 1725 break; | 1728 break; |
| 1726 | 1729 |
| 1727 if (icon_mappings[i].icon_url == icon_url) | 1730 if (icon_mappings[i].icon_url == icon_url) |
| 1728 continue; | 1731 continue; |
| 1729 | 1732 |
| 1730 std::vector<FaviconBitmap> bitmaps_to_copy; | 1733 std::vector<FaviconBitmap> bitmaps_to_copy; |
| 1731 thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, | 1734 thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, |
| 1732 &bitmaps_to_copy); | 1735 &bitmaps_to_copy); |
| 1733 for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { | 1736 for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { |
| 1734 // Do not add a favicon bitmap at a pixel size for which there is already | 1737 // Do not add a favicon bitmap at a pixel size for which there is already |
| 1735 // a favicon bitmap mapped to |icon_url|. The one there is more correct | 1738 // a favicon bitmap mapped to |icon_url|. The one there is more correct |
| 1736 // and having multiple equally sized favicon bitmaps for |page_url| is | 1739 // and having multiple equally sized favicon bitmaps for |page_url| is |
| 1737 // ambiguous in terms of GetFaviconsForURL(). | 1740 // ambiguous in terms of GetFaviconsForURL(). |
| 1738 std::vector<gfx::Size>::iterator it = | 1741 std::vector<gfx::Size>::iterator it = |
| 1739 std::find(favicon_sizes.begin(), favicon_sizes.end(), | 1742 std::find(favicon_sizes.begin(), favicon_sizes.end(), |
| 1740 bitmaps_to_copy[j].pixel_size); | 1743 bitmaps_to_copy[j].pixel_size); |
| 1741 if (it != favicon_sizes.end()) | 1744 if (it != favicon_sizes.end()) |
| 1742 continue; | 1745 continue; |
| 1743 | 1746 |
| 1744 // Add the favicon bitmap as expired as it is not consistent with the | 1747 // Add the favicon bitmap as expired as it is not consistent with the |
| 1745 // merged in data. | 1748 // merged in data. |
| 1746 thumbnail_db_->AddFaviconBitmap( | 1749 thumbnail_db_->AddFaviconBitmap( |
| 1747 favicon_id, bitmaps_to_copy[j].bitmap_data, base::Time(), | 1750 favicon_id, bitmaps_to_copy[j].bitmap_data, base::Time(), |
| 1748 bitmaps_to_copy[j].pixel_size); | 1751 bitmaps_to_copy[j].pixel_size); |
| 1749 favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); | 1752 favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); |
| 1753 favicon_bitmaps_copied = true; |
| 1750 | 1754 |
| 1751 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) | 1755 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) |
| 1752 break; | 1756 break; |
| 1753 } | 1757 } |
| 1754 } | 1758 } |
| 1755 | 1759 |
| 1756 // Update the favicon mappings such that only |icon_url| is mapped to | 1760 // Update the favicon mappings such that only |icon_url| is mapped to |
| 1757 // |page_url|. | 1761 // |page_url|. |
| 1758 bool mapping_changed = false; | |
| 1759 if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { | 1762 if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { |
| 1760 std::vector<favicon_base::FaviconID> favicon_ids; | 1763 std::vector<favicon_base::FaviconID> favicon_ids; |
| 1761 favicon_ids.push_back(favicon_id); | 1764 favicon_ids.push_back(favicon_id); |
| 1762 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); | 1765 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); |
| 1763 mapping_changed = true; | 1766 SendFaviconChangedNotificationForPageAndRedirects(page_url); |
| 1764 } | 1767 } |
| 1765 | 1768 |
| 1766 if (mapping_changed || !bitmap_identical) | 1769 if (!favicon_created && (!bitmap_identical || favicon_bitmaps_copied)) { |
| 1767 SendFaviconChangedNotificationForPageAndRedirects(page_url); | 1770 // If there was a favicon at |icon_url| prior to MergeFavicon() being |
| 1771 // called, there may be page URLs which also use the favicon at |icon_url|. |
| 1772 // Notify the UI that the favicon has changed for |icon_url|. |
| 1773 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1774 } |
| 1775 |
| 1768 ScheduleCommit(); | 1776 ScheduleCommit(); |
| 1769 } | 1777 } |
| 1770 | 1778 |
| 1771 void HistoryBackend::SetFavicons(const GURL& page_url, | 1779 void HistoryBackend::SetFavicons(const GURL& page_url, |
| 1772 favicon_base::IconType icon_type, | 1780 favicon_base::IconType icon_type, |
| 1773 const GURL& icon_url, | 1781 const GURL& icon_url, |
| 1774 const std::vector<SkBitmap>& bitmaps) { | 1782 const std::vector<SkBitmap>& bitmaps) { |
| 1775 if (!thumbnail_db_ || !db_) | 1783 if (!thumbnail_db_ || !db_) |
| 1776 return; | 1784 return; |
| 1777 | 1785 |
| 1778 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); | 1786 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); |
| 1779 | 1787 |
| 1780 // Track whether the method modifies or creates any favicon bitmaps, favicons | |
| 1781 // or icon mappings. | |
| 1782 bool data_modified = false; | |
| 1783 | |
| 1784 favicon_base::FaviconID icon_id = | 1788 favicon_base::FaviconID icon_id = |
| 1785 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1789 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
| 1786 | 1790 |
| 1791 bool favicon_created = false; |
| 1787 if (!icon_id) { | 1792 if (!icon_id) { |
| 1788 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1793 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
| 1789 data_modified = true; | 1794 favicon_created = true; |
| 1790 } | 1795 } |
| 1791 | 1796 |
| 1792 data_modified |= SetFaviconBitmaps(icon_id, bitmaps); | 1797 bool favicon_data_modified = SetFaviconBitmaps(icon_id, bitmaps); |
| 1793 | 1798 |
| 1794 std::vector<favicon_base::FaviconID> icon_ids(1u, icon_id); | 1799 std::vector<favicon_base::FaviconID> icon_ids(1u, icon_id); |
| 1795 data_modified |= | 1800 bool mapping_changed = |
| 1796 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); | 1801 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); |
| 1797 | 1802 |
| 1798 if (data_modified) { | 1803 if (mapping_changed) { |
| 1799 // Send notification to the UI as an icon mapping, favicon, or favicon | 1804 // Notify the UI that this function changed an icon mapping. |
| 1800 // bitmap was changed by this function. | |
| 1801 SendFaviconChangedNotificationForPageAndRedirects(page_url); | 1805 SendFaviconChangedNotificationForPageAndRedirects(page_url); |
| 1802 } | 1806 } |
| 1807 |
| 1808 if (favicon_data_modified && !favicon_created) { |
| 1809 // If there was a favicon at |icon_url| prior to SetFavicons() being called, |
| 1810 // there may be page URLs which also use the favicon at |icon_url|. Notify |
| 1811 // the UI that the favicon has changed for |icon_url|. |
| 1812 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1813 } |
| 1803 ScheduleCommit(); | 1814 ScheduleCommit(); |
| 1804 } | 1815 } |
| 1805 | 1816 |
| 1806 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { | 1817 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { |
| 1807 std::vector<IconMapping> icon_mappings; | 1818 std::vector<IconMapping> icon_mappings; |
| 1808 | 1819 |
| 1809 if (!thumbnail_db_ || | 1820 if (!thumbnail_db_ || |
| 1810 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) | 1821 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) |
| 1811 return; | 1822 return; |
| 1812 | 1823 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1867 // set already. | 1878 // set already. |
| 1868 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1879 thumbnail_db_->AddIconMapping(*url, favicon_id); |
| 1869 favicons_changed.insert(*url); | 1880 favicons_changed.insert(*url); |
| 1870 } | 1881 } |
| 1871 } | 1882 } |
| 1872 } | 1883 } |
| 1873 } | 1884 } |
| 1874 | 1885 |
| 1875 if (!favicons_changed.empty()) { | 1886 if (!favicons_changed.empty()) { |
| 1876 // Send the notification about the changed favicon URLs. | 1887 // Send the notification about the changed favicon URLs. |
| 1877 NotifyFaviconChanged(favicons_changed); | 1888 NotifyFaviconsChanged(favicons_changed, GURL()); |
| 1878 } | 1889 } |
| 1879 } | 1890 } |
| 1880 | 1891 |
| 1881 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( | 1892 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( |
| 1882 const GURL* page_url, | 1893 const GURL* page_url, |
| 1883 const std::vector<GURL>& icon_urls, | 1894 const std::vector<GURL>& icon_urls, |
| 1884 int icon_types, | 1895 int icon_types, |
| 1885 const std::vector<int>& desired_sizes, | 1896 const std::vector<int>& desired_sizes, |
| 1886 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1897 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
| 1887 // If |page_url| is specified, |icon_types| must be either a single icon | 1898 // 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... |
| 2212 // No known redirects, construct mock redirect chain containing |page_url|. | 2223 // No known redirects, construct mock redirect chain containing |page_url|. |
| 2213 redirect_list->push_back(page_url); | 2224 redirect_list->push_back(page_url); |
| 2214 } | 2225 } |
| 2215 } | 2226 } |
| 2216 | 2227 |
| 2217 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( | 2228 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( |
| 2218 const GURL& page_url) { | 2229 const GURL& page_url) { |
| 2219 RedirectList redirect_list; | 2230 RedirectList redirect_list; |
| 2220 GetCachedRecentRedirects(page_url, &redirect_list); | 2231 GetCachedRecentRedirects(page_url, &redirect_list); |
| 2221 if (!redirect_list.empty()) { | 2232 if (!redirect_list.empty()) { |
| 2222 std::set<GURL> favicons_changed(redirect_list.begin(), redirect_list.end()); | 2233 std::set<GURL> favicons_changed(redirect_list.begin(), |
| 2223 NotifyFaviconChanged(favicons_changed); | 2234 redirect_list.end()); |
| 2235 NotifyFaviconsChanged(favicons_changed, GURL()); |
| 2224 } | 2236 } |
| 2225 } | 2237 } |
| 2226 | 2238 |
| 2239 void HistoryBackend::SendFaviconChangedNotificationForIconURL( |
| 2240 const GURL& icon_url) { |
| 2241 NotifyFaviconsChanged(std::set<GURL>(), icon_url); |
| 2242 } |
| 2243 |
| 2227 void HistoryBackend::Commit() { | 2244 void HistoryBackend::Commit() { |
| 2228 if (!db_) | 2245 if (!db_) |
| 2229 return; | 2246 return; |
| 2230 | 2247 |
| 2231 #if defined(OS_IOS) | 2248 #if defined(OS_IOS) |
| 2232 // Attempts to get the application running long enough to commit the database | 2249 // Attempts to get the application running long enough to commit the database |
| 2233 // transaction if it is currently being backgrounded. | 2250 // transaction if it is currently being backgrounded. |
| 2234 base::ios::ScopedCriticalAction scoped_critical_action; | 2251 base::ios::ScopedCriticalAction scoped_critical_action; |
| 2235 #endif | 2252 #endif |
| 2236 | 2253 |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 scoped_ptr<HistoryDBTask> task, | 2516 scoped_ptr<HistoryDBTask> task, |
| 2500 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, | 2517 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, |
| 2501 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { | 2518 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { |
| 2502 bool scheduled = !queued_history_db_tasks_.empty(); | 2519 bool scheduled = !queued_history_db_tasks_.empty(); |
| 2503 queued_history_db_tasks_.push_back( | 2520 queued_history_db_tasks_.push_back( |
| 2504 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); | 2521 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); |
| 2505 if (!scheduled) | 2522 if (!scheduled) |
| 2506 ProcessDBTaskImpl(); | 2523 ProcessDBTaskImpl(); |
| 2507 } | 2524 } |
| 2508 | 2525 |
| 2509 void HistoryBackend::NotifyFaviconChanged(const std::set<GURL>& urls) { | 2526 void HistoryBackend::NotifyFaviconsChanged(const std::set<GURL>& page_urls, |
| 2527 const GURL& icon_url) { |
| 2510 if (delegate_) | 2528 if (delegate_) |
| 2511 delegate_->NotifyFaviconChanged(urls); | 2529 delegate_->NotifyFaviconsChanged(page_urls, icon_url); |
| 2512 } | 2530 } |
| 2513 | 2531 |
| 2514 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, | 2532 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, |
| 2515 const URLRow& row, | 2533 const URLRow& row, |
| 2516 const RedirectList& redirects, | 2534 const RedirectList& redirects, |
| 2517 base::Time visit_time) { | 2535 base::Time visit_time) { |
| 2518 URLRow url_info(row); | 2536 URLRow url_info(row); |
| 2519 if (typed_url_syncable_service_.get()) | 2537 if (typed_url_syncable_service_.get()) |
| 2520 typed_url_syncable_service_->OnUrlVisited(transition, &url_info); | 2538 typed_url_syncable_service_->OnUrlVisited(transition, &url_info); |
| 2521 | 2539 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2689 // transaction is currently open. | 2707 // transaction is currently open. |
| 2690 db_->CommitTransaction(); | 2708 db_->CommitTransaction(); |
| 2691 db_->Vacuum(); | 2709 db_->Vacuum(); |
| 2692 db_->BeginTransaction(); | 2710 db_->BeginTransaction(); |
| 2693 db_->GetStartDate(&first_recorded_time_); | 2711 db_->GetStartDate(&first_recorded_time_); |
| 2694 | 2712 |
| 2695 return true; | 2713 return true; |
| 2696 } | 2714 } |
| 2697 | 2715 |
| 2698 } // namespace history | 2716 } // namespace history |
| OLD | NEW |