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 1574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1585 const GURL& icon_url, | 1585 const GURL& icon_url, |
1586 favicon_base::IconType icon_type, | 1586 favicon_base::IconType icon_type, |
1587 scoped_refptr<base::RefCountedMemory> bitmap_data, | 1587 scoped_refptr<base::RefCountedMemory> bitmap_data, |
1588 const gfx::Size& pixel_size) { | 1588 const gfx::Size& pixel_size) { |
1589 if (!thumbnail_db_ || !db_) | 1589 if (!thumbnail_db_ || !db_) |
1590 return; | 1590 return; |
1591 | 1591 |
1592 favicon_base::FaviconID favicon_id = | 1592 favicon_base::FaviconID favicon_id = |
1593 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1593 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
1594 | 1594 |
| 1595 bool favicon_created = false; |
1595 if (!favicon_id) { | 1596 if (!favicon_id) { |
1596 // There is no favicon at |icon_url|, create it. | 1597 // There is no favicon at |icon_url|, create it. |
1597 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1598 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
| 1599 favicon_created = true; |
1598 } | 1600 } |
1599 | 1601 |
1600 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; | 1602 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; |
1601 thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); | 1603 thumbnail_db_->GetFaviconBitmapIDSizes(favicon_id, &bitmap_id_sizes); |
1602 | 1604 |
1603 // If there is already a favicon bitmap of |pixel_size| at |icon_url|, | 1605 // If there is already a favicon bitmap of |pixel_size| at |icon_url|, |
1604 // replace it. | 1606 // replace it. |
1605 bool bitmap_identical = false; | 1607 bool bitmap_identical = false; |
1606 bool replaced_bitmap = false; | 1608 bool replaced_bitmap = false; |
1607 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { | 1609 for (size_t i = 0; i < bitmap_id_sizes.size(); ++i) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1675 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from | 1677 // Difficulty 1: All but news.google.com/news_specific.ico are unmapped from |
1676 // news.google.com | 1678 // news.google.com |
1677 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not | 1679 // Difficulty 2: The favicon bitmaps for www.google.com/favicon.ico are not |
1678 // modified. | 1680 // modified. |
1679 | 1681 |
1680 std::vector<IconMapping> icon_mappings; | 1682 std::vector<IconMapping> icon_mappings; |
1681 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); | 1683 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, &icon_mappings); |
1682 | 1684 |
1683 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| | 1685 // Copy the favicon bitmaps mapped to |page_url| to the favicon at |icon_url| |
1684 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. | 1686 // till the limit of |kMaxFaviconBitmapsPerIconURL| is reached. |
| 1687 bool favicon_bitmaps_copied = false; |
1685 for (size_t i = 0; i < icon_mappings.size(); ++i) { | 1688 for (size_t i = 0; i < icon_mappings.size(); ++i) { |
1686 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) | 1689 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) |
1687 break; | 1690 break; |
1688 | 1691 |
1689 if (icon_mappings[i].icon_url == icon_url) | 1692 if (icon_mappings[i].icon_url == icon_url) |
1690 continue; | 1693 continue; |
1691 | 1694 |
1692 std::vector<FaviconBitmap> bitmaps_to_copy; | 1695 std::vector<FaviconBitmap> bitmaps_to_copy; |
1693 thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, | 1696 thumbnail_db_->GetFaviconBitmaps(icon_mappings[i].icon_id, |
1694 &bitmaps_to_copy); | 1697 &bitmaps_to_copy); |
1695 for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { | 1698 for (size_t j = 0; j < bitmaps_to_copy.size(); ++j) { |
1696 // Do not add a favicon bitmap at a pixel size for which there is already | 1699 // Do not add a favicon bitmap at a pixel size for which there is already |
1697 // a favicon bitmap mapped to |icon_url|. The one there is more correct | 1700 // a favicon bitmap mapped to |icon_url|. The one there is more correct |
1698 // and having multiple equally sized favicon bitmaps for |page_url| is | 1701 // and having multiple equally sized favicon bitmaps for |page_url| is |
1699 // ambiguous in terms of GetFaviconsForURL(). | 1702 // ambiguous in terms of GetFaviconsForURL(). |
1700 std::vector<gfx::Size>::iterator it = | 1703 std::vector<gfx::Size>::iterator it = |
1701 std::find(favicon_sizes.begin(), favicon_sizes.end(), | 1704 std::find(favicon_sizes.begin(), favicon_sizes.end(), |
1702 bitmaps_to_copy[j].pixel_size); | 1705 bitmaps_to_copy[j].pixel_size); |
1703 if (it != favicon_sizes.end()) | 1706 if (it != favicon_sizes.end()) |
1704 continue; | 1707 continue; |
1705 | 1708 |
1706 // Add the favicon bitmap as expired as it is not consistent with the | 1709 // Add the favicon bitmap as expired as it is not consistent with the |
1707 // merged in data. | 1710 // merged in data. |
1708 thumbnail_db_->AddFaviconBitmap( | 1711 thumbnail_db_->AddFaviconBitmap( |
1709 favicon_id, bitmaps_to_copy[j].bitmap_data, base::Time(), | 1712 favicon_id, bitmaps_to_copy[j].bitmap_data, base::Time(), |
1710 bitmaps_to_copy[j].pixel_size); | 1713 bitmaps_to_copy[j].pixel_size); |
1711 favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); | 1714 favicon_sizes.push_back(bitmaps_to_copy[j].pixel_size); |
| 1715 favicon_bitmaps_copied = true; |
1712 | 1716 |
1713 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) | 1717 if (favicon_sizes.size() >= kMaxFaviconBitmapsPerIconURL) |
1714 break; | 1718 break; |
1715 } | 1719 } |
1716 } | 1720 } |
1717 | 1721 |
1718 // Update the favicon mappings such that only |icon_url| is mapped to | 1722 // Update the favicon mappings such that only |icon_url| is mapped to |
1719 // |page_url|. | 1723 // |page_url|. |
1720 bool mapping_changed = false; | 1724 bool mapping_changed = false; |
1721 if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { | 1725 if (icon_mappings.size() != 1 || icon_mappings[0].icon_url != icon_url) { |
1722 std::vector<favicon_base::FaviconID> favicon_ids; | 1726 std::vector<favicon_base::FaviconID> favicon_ids; |
1723 favicon_ids.push_back(favicon_id); | 1727 favicon_ids.push_back(favicon_id); |
1724 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); | 1728 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, favicon_ids); |
1725 mapping_changed = true; | 1729 mapping_changed = true; |
1726 } | 1730 } |
1727 | 1731 |
1728 if (mapping_changed || !bitmap_identical) | 1732 if (mapping_changed) |
1729 SendFaviconChangedNotificationForPageAndRedirects(page_url); | 1733 SendFaviconChangedNotificationForPageAndRedirects(page_url); |
| 1734 |
| 1735 if (!favicon_created && (!bitmap_identical || favicon_bitmaps_copied)) { |
| 1736 // If there was a favicon at |icon_url| prior to MergeFavicon() being |
| 1737 // called, there may be page URLs which also use the favicon at |icon_url|. |
| 1738 // Notify the UI that the favicon has changed for |icon_url|. |
| 1739 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1740 } |
| 1741 |
1730 ScheduleCommit(); | 1742 ScheduleCommit(); |
1731 } | 1743 } |
1732 | 1744 |
1733 void HistoryBackend::SetFavicons(const GURL& page_url, | 1745 void HistoryBackend::SetFavicons(const GURL& page_url, |
1734 favicon_base::IconType icon_type, | 1746 favicon_base::IconType icon_type, |
1735 const GURL& icon_url, | 1747 const GURL& icon_url, |
1736 const std::vector<SkBitmap>& bitmaps) { | 1748 const std::vector<SkBitmap>& bitmaps) { |
1737 if (!thumbnail_db_ || !db_) | 1749 if (!thumbnail_db_ || !db_) |
1738 return; | 1750 return; |
1739 | 1751 |
1740 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); | 1752 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); |
1741 | 1753 |
1742 // Track whether the method modifies or creates any favicon bitmaps, favicons | |
1743 // or icon mappings. | |
1744 bool data_modified = false; | |
1745 | |
1746 favicon_base::FaviconID icon_id = | 1754 favicon_base::FaviconID icon_id = |
1747 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1755 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
1748 | 1756 |
| 1757 bool favicon_created = false; |
1749 if (!icon_id) { | 1758 if (!icon_id) { |
1750 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1759 icon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
1751 data_modified = true; | 1760 favicon_created = true; |
1752 } | 1761 } |
1753 | 1762 |
1754 data_modified |= SetFaviconBitmaps(icon_id, bitmaps); | 1763 bool favicon_data_modified = SetFaviconBitmaps(icon_id, bitmaps); |
1755 | 1764 |
1756 std::vector<favicon_base::FaviconID> icon_ids(1u, icon_id); | 1765 std::vector<favicon_base::FaviconID> icon_ids(1u, icon_id); |
1757 data_modified |= | 1766 bool mapping_changed = |
1758 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); | 1767 SetFaviconMappingsForPageAndRedirects(page_url, icon_type, icon_ids); |
1759 | 1768 |
1760 if (data_modified) { | 1769 if (mapping_changed) { |
1761 // Send notification to the UI as an icon mapping, favicon, or favicon | 1770 // Notify the UI that this function changed an icon mapping. |
1762 // bitmap was changed by this function. | |
1763 SendFaviconChangedNotificationForPageAndRedirects(page_url); | 1771 SendFaviconChangedNotificationForPageAndRedirects(page_url); |
1764 } | 1772 } |
| 1773 |
| 1774 if (favicon_data_modified && !favicon_created) { |
| 1775 // If there was a favicon at |icon_url| prior to SetFavicons() being called, |
| 1776 // there may be page URLs which also use the favicon at |icon_url|. Notify |
| 1777 // the UI that the favicon has changed for |icon_url|. |
| 1778 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1779 } |
1765 ScheduleCommit(); | 1780 ScheduleCommit(); |
1766 } | 1781 } |
1767 | 1782 |
1768 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { | 1783 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { |
1769 std::vector<IconMapping> icon_mappings; | 1784 std::vector<IconMapping> icon_mappings; |
1770 | 1785 |
1771 if (!thumbnail_db_ || | 1786 if (!thumbnail_db_ || |
1772 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) | 1787 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) |
1773 return; | 1788 return; |
1774 | 1789 |
1775 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 1790 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
1776 m != icon_mappings.end(); ++m) { | 1791 m != icon_mappings.end(); ++m) { |
1777 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); | 1792 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); |
1778 } | 1793 } |
1779 ScheduleCommit(); | 1794 ScheduleCommit(); |
1780 } | 1795 } |
1781 | 1796 |
1782 void HistoryBackend::SetImportedFavicons( | 1797 void HistoryBackend::SetImportedFavicons( |
1783 const favicon_base::FaviconUsageDataList& favicon_usage) { | 1798 const favicon_base::FaviconUsageDataList& favicon_usage) { |
1784 if (!db_ || !thumbnail_db_) | 1799 if (!db_ || !thumbnail_db_) |
1785 return; | 1800 return; |
1786 | 1801 |
1787 Time now = Time::Now(); | 1802 Time now = Time::Now(); |
1788 | 1803 |
1789 // Track all URLs that had their favicons set or updated. | 1804 // Track all URLs that had their favicons set or updated. |
1790 std::set<GURL> favicons_changed; | 1805 std::vector<GURL> favicons_changed; |
1791 | 1806 |
1792 for (size_t i = 0; i < favicon_usage.size(); i++) { | 1807 for (size_t i = 0; i < favicon_usage.size(); i++) { |
1793 favicon_base::FaviconID favicon_id = | 1808 favicon_base::FaviconID favicon_id = |
1794 thumbnail_db_->GetFaviconIDForFaviconURL( | 1809 thumbnail_db_->GetFaviconIDForFaviconURL( |
1795 favicon_usage[i].favicon_url, favicon_base::FAVICON, nullptr); | 1810 favicon_usage[i].favicon_url, favicon_base::FAVICON, nullptr); |
1796 if (!favicon_id) { | 1811 if (!favicon_id) { |
1797 // This favicon doesn't exist yet, so we create it using the given data. | 1812 // This favicon doesn't exist yet, so we create it using the given data. |
1798 // TODO(pkotwicz): Pass in real pixel size. | 1813 // TODO(pkotwicz): Pass in real pixel size. |
1799 favicon_id = thumbnail_db_->AddFavicon( | 1814 favicon_id = thumbnail_db_->AddFavicon( |
1800 favicon_usage[i].favicon_url, favicon_base::FAVICON, | 1815 favicon_usage[i].favicon_url, favicon_base::FAVICON, |
(...skipping 13 matching lines...) Expand all Loading... |
1814 // cleaned, we keep an entry in the db with 0 visits as long as that | 1829 // cleaned, we keep an entry in the db with 0 visits as long as that |
1815 // url is bookmarked. | 1830 // url is bookmarked. |
1816 if (history_client && history_client->IsBookmarked(*url)) { | 1831 if (history_client && history_client->IsBookmarked(*url)) { |
1817 URLRow url_info(*url); | 1832 URLRow url_info(*url); |
1818 url_info.set_visit_count(0); | 1833 url_info.set_visit_count(0); |
1819 url_info.set_typed_count(0); | 1834 url_info.set_typed_count(0); |
1820 url_info.set_last_visit(base::Time()); | 1835 url_info.set_last_visit(base::Time()); |
1821 url_info.set_hidden(false); | 1836 url_info.set_hidden(false); |
1822 db_->AddURL(url_info); | 1837 db_->AddURL(url_info); |
1823 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1838 thumbnail_db_->AddIconMapping(*url, favicon_id); |
1824 favicons_changed.insert(*url); | 1839 favicons_changed.push_back(*url); |
1825 } | 1840 } |
1826 } else { | 1841 } else { |
1827 if (!thumbnail_db_->GetIconMappingsForPageURL( | 1842 if (!thumbnail_db_->GetIconMappingsForPageURL( |
1828 *url, favicon_base::FAVICON, nullptr)) { | 1843 *url, favicon_base::FAVICON, nullptr)) { |
1829 // URL is present in history, update the favicon *only* if it is not | 1844 // URL is present in history, update the favicon *only* if it is not |
1830 // set already. | 1845 // set already. |
1831 thumbnail_db_->AddIconMapping(*url, favicon_id); | 1846 thumbnail_db_->AddIconMapping(*url, favicon_id); |
1832 favicons_changed.insert(*url); | 1847 favicons_changed.push_back(*url); |
1833 } | 1848 } |
1834 } | 1849 } |
1835 } | 1850 } |
1836 } | 1851 } |
1837 | 1852 |
1838 if (!favicons_changed.empty()) { | 1853 if (!favicons_changed.empty()) { |
1839 // Send the notification about the changed favicon URLs. | 1854 // Send the notification about the changed favicon URLs. |
1840 NotifyFaviconChanged(favicons_changed); | 1855 NotifyFaviconsChanged(favicons_changed, std::vector<GURL>()); |
1841 } | 1856 } |
1842 } | 1857 } |
1843 | 1858 |
1844 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( | 1859 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( |
1845 const GURL* page_url, | 1860 const GURL* page_url, |
1846 const std::vector<GURL>& icon_urls, | 1861 const std::vector<GURL>& icon_urls, |
1847 int icon_types, | 1862 int icon_types, |
1848 const std::vector<int>& desired_sizes, | 1863 const std::vector<int>& desired_sizes, |
1849 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1864 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
1850 // If |page_url| is specified, |icon_types| must be either a single icon | 1865 // 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... |
2159 // No known redirects, construct mock redirect chain containing |page_url|. | 2174 // No known redirects, construct mock redirect chain containing |page_url|. |
2160 redirect_list->push_back(page_url); | 2175 redirect_list->push_back(page_url); |
2161 } | 2176 } |
2162 } | 2177 } |
2163 | 2178 |
2164 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( | 2179 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( |
2165 const GURL& page_url) { | 2180 const GURL& page_url) { |
2166 RedirectList redirect_list; | 2181 RedirectList redirect_list; |
2167 GetCachedRecentRedirects(page_url, &redirect_list); | 2182 GetCachedRecentRedirects(page_url, &redirect_list); |
2168 if (!redirect_list.empty()) { | 2183 if (!redirect_list.empty()) { |
2169 std::set<GURL> favicons_changed(redirect_list.begin(), redirect_list.end()); | 2184 std::vector<GURL> favicons_changed(redirect_list.begin(), |
2170 NotifyFaviconChanged(favicons_changed); | 2185 redirect_list.end()); |
| 2186 NotifyFaviconsChanged(favicons_changed, std::vector<GURL>()); |
2171 } | 2187 } |
2172 } | 2188 } |
2173 | 2189 |
| 2190 void HistoryBackend::SendFaviconChangedNotificationForIconURL( |
| 2191 const GURL& icon_url) { |
| 2192 NotifyFaviconsChanged(std::vector<GURL>(), |
| 2193 std::vector<GURL>(1u, icon_url)); |
| 2194 } |
| 2195 |
2174 void HistoryBackend::Commit() { | 2196 void HistoryBackend::Commit() { |
2175 if (!db_) | 2197 if (!db_) |
2176 return; | 2198 return; |
2177 | 2199 |
2178 #if defined(OS_IOS) | 2200 #if defined(OS_IOS) |
2179 // Attempts to get the application running long enough to commit the database | 2201 // Attempts to get the application running long enough to commit the database |
2180 // transaction if it is currently being backgrounded. | 2202 // transaction if it is currently being backgrounded. |
2181 base::ios::ScopedCriticalAction scoped_critical_action; | 2203 base::ios::ScopedCriticalAction scoped_critical_action; |
2182 #endif | 2204 #endif |
2183 | 2205 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2446 scoped_ptr<HistoryDBTask> task, | 2468 scoped_ptr<HistoryDBTask> task, |
2447 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, | 2469 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, |
2448 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { | 2470 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { |
2449 bool scheduled = !queued_history_db_tasks_.empty(); | 2471 bool scheduled = !queued_history_db_tasks_.empty(); |
2450 queued_history_db_tasks_.push_back( | 2472 queued_history_db_tasks_.push_back( |
2451 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); | 2473 new QueuedHistoryDBTask(task.Pass(), origin_loop, is_canceled)); |
2452 if (!scheduled) | 2474 if (!scheduled) |
2453 ProcessDBTaskImpl(); | 2475 ProcessDBTaskImpl(); |
2454 } | 2476 } |
2455 | 2477 |
2456 void HistoryBackend::NotifyFaviconChanged(const std::set<GURL>& urls) { | 2478 void HistoryBackend::NotifyFaviconsChanged(const std::vector<GURL>& page_urls, |
| 2479 const std::vector<GURL>& icon_urls) { |
2457 if (delegate_) | 2480 if (delegate_) |
2458 delegate_->NotifyFaviconChanged(urls); | 2481 delegate_->NotifyFaviconsChanged(page_urls, icon_urls); |
2459 } | 2482 } |
2460 | 2483 |
2461 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, | 2484 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, |
2462 const URLRow& row, | 2485 const URLRow& row, |
2463 const RedirectList& redirects, | 2486 const RedirectList& redirects, |
2464 base::Time visit_time) { | 2487 base::Time visit_time) { |
2465 URLRow url_info(row); | 2488 URLRow url_info(row); |
2466 if (typed_url_syncable_service_.get()) | 2489 if (typed_url_syncable_service_.get()) |
2467 typed_url_syncable_service_->OnUrlVisited(transition, &url_info); | 2490 typed_url_syncable_service_->OnUrlVisited(transition, &url_info); |
2468 | 2491 |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2647 return true; | 2670 return true; |
2648 } | 2671 } |
2649 | 2672 |
2650 HistoryClient* HistoryBackend::GetHistoryClient() { | 2673 HistoryClient* HistoryBackend::GetHistoryClient() { |
2651 if (history_client_) | 2674 if (history_client_) |
2652 history_client_->BlockUntilBookmarksLoaded(); | 2675 history_client_->BlockUntilBookmarksLoaded(); |
2653 return history_client_; | 2676 return history_client_; |
2654 } | 2677 } |
2655 | 2678 |
2656 } // namespace history | 2679 } // namespace history |
OLD | NEW |