| 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 <list> | 7 #include <list> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 1777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 void HistoryBackend::SetFaviconOutOfDateForPage(const GURL& page_url) { | 1788 void HistoryBackend::SetFaviconOutOfDateForPage(const GURL& page_url) { |
| 1789 std::vector<IconMapping> icon_mappings; | 1789 std::vector<IconMapping> icon_mappings; |
| 1790 | 1790 |
| 1791 if (!thumbnail_db_.get() || | 1791 if (!thumbnail_db_.get() || |
| 1792 !thumbnail_db_->GetIconMappingsForPageURL(page_url, | 1792 !thumbnail_db_->GetIconMappingsForPageURL(page_url, |
| 1793 &icon_mappings)) | 1793 &icon_mappings)) |
| 1794 return; | 1794 return; |
| 1795 | 1795 |
| 1796 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 1796 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
| 1797 m != icon_mappings.end(); ++m) { | 1797 m != icon_mappings.end(); ++m) { |
| 1798 thumbnail_db_->SetFaviconLastUpdateTime(m->icon_id, Time()); | 1798 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); |
| 1799 } | 1799 } |
| 1800 ScheduleCommit(); | 1800 ScheduleCommit(); |
| 1801 } | 1801 } |
| 1802 | 1802 |
| 1803 void HistoryBackend::CloneFavicon(const GURL& old_page_url, | 1803 void HistoryBackend::CloneFavicon(const GURL& old_page_url, |
| 1804 const GURL& new_page_url) { | 1804 const GURL& new_page_url) { |
| 1805 if (!thumbnail_db_.get()) | 1805 if (!thumbnail_db_.get()) |
| 1806 return; | 1806 return; |
| 1807 | 1807 |
| 1808 // Prevent cross-domain cloning. | 1808 // Prevent cross-domain cloning. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1821 Time now = Time::Now(); | 1821 Time now = Time::Now(); |
| 1822 | 1822 |
| 1823 // Track all URLs that had their favicons set or updated. | 1823 // Track all URLs that had their favicons set or updated. |
| 1824 std::set<GURL> favicons_changed; | 1824 std::set<GURL> favicons_changed; |
| 1825 | 1825 |
| 1826 for (size_t i = 0; i < favicon_usage.size(); i++) { | 1826 for (size_t i = 0; i < favicon_usage.size(); i++) { |
| 1827 FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL( | 1827 FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL( |
| 1828 favicon_usage[i].favicon_url, history::FAVICON, NULL); | 1828 favicon_usage[i].favicon_url, history::FAVICON, NULL); |
| 1829 if (!favicon_id) { | 1829 if (!favicon_id) { |
| 1830 // This favicon doesn't exist yet, so we create it using the given data. | 1830 // This favicon doesn't exist yet, so we create it using the given data. |
| 1831 favicon_id = thumbnail_db_->AddFavicon(favicon_usage[i].favicon_url, | 1831 // TODO(pkotwicz): Pass in real pixel size. |
| 1832 history::FAVICON); | 1832 favicon_id = thumbnail_db_->AddFavicon( |
| 1833 if (!favicon_id) | 1833 favicon_usage[i].favicon_url, |
| 1834 continue; // Unable to add the favicon. | 1834 history::FAVICON, |
| 1835 thumbnail_db_->SetFavicon(favicon_id, | 1835 std::string("0 0"), |
| 1836 new base::RefCountedBytes(favicon_usage[i].png_data), now); | 1836 new base::RefCountedBytes(favicon_usage[i].png_data), |
| 1837 now, |
| 1838 gfx::Size()); |
| 1837 } | 1839 } |
| 1838 | 1840 |
| 1839 // Save the mapping from all the URLs to the favicon. | 1841 // Save the mapping from all the URLs to the favicon. |
| 1840 BookmarkService* bookmark_service = GetBookmarkService(); | 1842 BookmarkService* bookmark_service = GetBookmarkService(); |
| 1841 for (std::set<GURL>::const_iterator url = favicon_usage[i].urls.begin(); | 1843 for (std::set<GURL>::const_iterator url = favicon_usage[i].urls.begin(); |
| 1842 url != favicon_usage[i].urls.end(); ++url) { | 1844 url != favicon_usage[i].urls.end(); ++url) { |
| 1843 URLRow url_row; | 1845 URLRow url_row; |
| 1844 if (!db_->GetRowForURL(*url, &url_row)) { | 1846 if (!db_->GetRowForURL(*url, &url_row)) { |
| 1845 // If the URL is present as a bookmark, add the url in history to | 1847 // If the URL is present as a bookmark, add the url in history to |
| 1846 // save the favicon mapping. This will match with what history db does | 1848 // save the favicon mapping. This will match with what history db does |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1889 if (request->canceled()) | 1891 if (request->canceled()) |
| 1890 return; | 1892 return; |
| 1891 | 1893 |
| 1892 FaviconData favicon; | 1894 FaviconData favicon; |
| 1893 | 1895 |
| 1894 if (thumbnail_db_.get()) { | 1896 if (thumbnail_db_.get()) { |
| 1895 const FaviconID favicon_id = | 1897 const FaviconID favicon_id = |
| 1896 thumbnail_db_->GetFaviconIDForFaviconURL( | 1898 thumbnail_db_->GetFaviconIDForFaviconURL( |
| 1897 icon_url, icon_types, &favicon.icon_type); | 1899 icon_url, icon_types, &favicon.icon_type); |
| 1898 if (favicon_id) { | 1900 if (favicon_id) { |
| 1899 scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes(); | 1901 scoped_refptr<base::RefCountedMemory> data; |
| 1900 favicon.known_icon = true; | 1902 favicon.known_icon = true; |
| 1901 Time last_updated; | 1903 Time last_updated; |
| 1902 if (thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data->data(), | 1904 if (thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data, |
| 1903 NULL, NULL)) { | 1905 NULL, NULL)) { |
| 1904 favicon.expired = (Time::Now() - last_updated) > | 1906 favicon.expired = (Time::Now() - last_updated) > |
| 1905 TimeDelta::FromDays(kFaviconRefetchDays); | 1907 TimeDelta::FromDays(kFaviconRefetchDays); |
| 1906 favicon.image_data = data; | 1908 favicon.image_data = data; |
| 1907 } | 1909 } |
| 1908 | 1910 |
| 1909 if (page_url) | 1911 if (page_url) |
| 1910 SetFaviconMapping(*page_url, favicon_id, favicon.icon_type); | 1912 SetFaviconMapping(*page_url, favicon_id, favicon.icon_type); |
| 1911 } | 1913 } |
| 1912 // else case, haven't cached entry yet. Caller is responsible for | 1914 // else case, haven't cached entry yet. Caller is responsible for |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1944 const GURL& page_url, | 1946 const GURL& page_url, |
| 1945 const GURL& icon_url, | 1947 const GURL& icon_url, |
| 1946 scoped_refptr<base::RefCountedMemory> data, | 1948 scoped_refptr<base::RefCountedMemory> data, |
| 1947 IconType icon_type) { | 1949 IconType icon_type) { |
| 1948 DCHECK(data.get()); | 1950 DCHECK(data.get()); |
| 1949 if (!thumbnail_db_.get() || !db_.get()) | 1951 if (!thumbnail_db_.get() || !db_.get()) |
| 1950 return; | 1952 return; |
| 1951 | 1953 |
| 1952 FaviconID id = thumbnail_db_->GetFaviconIDForFaviconURL( | 1954 FaviconID id = thumbnail_db_->GetFaviconIDForFaviconURL( |
| 1953 icon_url, icon_type, NULL); | 1955 icon_url, icon_type, NULL); |
| 1954 if (!id) | 1956 if (id) |
| 1955 id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1957 thumbnail_db_->DeleteFaviconBitmapsForFavicon(id); |
| 1956 | 1958 |
| 1957 // Set the image data. | 1959 id = thumbnail_db_->AddFavicon(icon_url, |
| 1958 thumbnail_db_->SetFavicon(id, data, Time::Now()); | 1960 icon_type, |
| 1961 "0 0", |
| 1962 data, |
| 1963 Time::Now(), |
| 1964 gfx::Size()); |
| 1959 | 1965 |
| 1960 SetFaviconMapping(page_url, id, icon_type); | 1966 SetFaviconMapping(page_url, id, icon_type); |
| 1961 } | 1967 } |
| 1962 | 1968 |
| 1963 void HistoryBackend::SetFaviconMapping(const GURL& page_url, | 1969 void HistoryBackend::SetFaviconMapping(const GURL& page_url, |
| 1964 FaviconID id, | 1970 FaviconID id, |
| 1965 IconType icon_type) { | 1971 IconType icon_type) { |
| 1966 if (!thumbnail_db_.get()) | 1972 if (!thumbnail_db_.get()) |
| 1967 return; | 1973 return; |
| 1968 | 1974 |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2327 bool HistoryBackend::ClearAllThumbnailHistory(URLRows* kept_urls) { | 2333 bool HistoryBackend::ClearAllThumbnailHistory(URLRows* kept_urls) { |
| 2328 if (!thumbnail_db_.get()) { | 2334 if (!thumbnail_db_.get()) { |
| 2329 // When we have no reference to the thumbnail database, maybe there was an | 2335 // When we have no reference to the thumbnail database, maybe there was an |
| 2330 // error opening it. In this case, we just try to blow it away to try to | 2336 // error opening it. In this case, we just try to blow it away to try to |
| 2331 // fix the error if it exists. This may fail, in which case either the | 2337 // fix the error if it exists. This may fail, in which case either the |
| 2332 // file doesn't exist or there's no more we can do. | 2338 // file doesn't exist or there's no more we can do. |
| 2333 file_util::Delete(GetThumbnailFileName(), false); | 2339 file_util::Delete(GetThumbnailFileName(), false); |
| 2334 return true; | 2340 return true; |
| 2335 } | 2341 } |
| 2336 | 2342 |
| 2337 // Create the duplicate favicon table, this is where the favicons we want | 2343 // Create duplicate icon_mapping, favicon, and favicon_bitmaps tables, this |
| 2338 // to keep will be stored. | 2344 // is where the favicons we want to keep will be stored. |
| 2339 if (!thumbnail_db_->InitTemporaryFaviconsTable()) | 2345 if (!thumbnail_db_->InitTemporaryTables()) |
| 2340 return false; | |
| 2341 | |
| 2342 if (!thumbnail_db_->InitTemporaryIconMappingTable()) | |
| 2343 return false; | 2346 return false; |
| 2344 | 2347 |
| 2345 // This maps existing favicon IDs to the ones in the temporary table. | 2348 // This maps existing favicon IDs to the ones in the temporary table. |
| 2346 typedef std::map<FaviconID, FaviconID> FaviconMap; | 2349 typedef std::map<FaviconID, FaviconID> FaviconMap; |
| 2347 FaviconMap copied_favicons; | 2350 FaviconMap copied_favicons; |
| 2348 | 2351 |
| 2349 // Copy all unique favicons to the temporary table, and update all the | 2352 // Copy all unique favicons to the temporary table, and update all the |
| 2350 // URLs to have the new IDs. | 2353 // URLs to have the new IDs. |
| 2351 for (URLRows::iterator i = kept_urls->begin(); i != kept_urls->end(); ++i) { | 2354 for (URLRows::iterator i = kept_urls->begin(); i != kept_urls->end(); ++i) { |
| 2352 std::vector<IconMapping> icon_mappings; | 2355 std::vector<IconMapping> icon_mappings; |
| 2353 if (!thumbnail_db_->GetIconMappingsForPageURL(i->url(), &icon_mappings)) | 2356 if (!thumbnail_db_->GetIconMappingsForPageURL(i->url(), &icon_mappings)) |
| 2354 continue; | 2357 continue; |
| 2355 | 2358 |
| 2356 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 2359 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
| 2357 m != icon_mappings.end(); ++m) { | 2360 m != icon_mappings.end(); ++m) { |
| 2358 FaviconID old_id = m->icon_id; | 2361 FaviconID old_id = m->icon_id; |
| 2359 FaviconID new_id; | 2362 FaviconID new_id; |
| 2360 FaviconMap::const_iterator found = copied_favicons.find(old_id); | 2363 FaviconMap::const_iterator found = copied_favicons.find(old_id); |
| 2361 if (found == copied_favicons.end()) { | 2364 if (found == copied_favicons.end()) { |
| 2362 new_id = thumbnail_db_->CopyToTemporaryFaviconTable(old_id); | 2365 new_id = thumbnail_db_->CopyFaviconAndFaviconBitmapsToTemporaryTables( |
| 2366 old_id); |
| 2363 copied_favicons[old_id] = new_id; | 2367 copied_favicons[old_id] = new_id; |
| 2364 } else { | 2368 } else { |
| 2365 // We already encountered a URL that used this favicon, use the ID we | 2369 // We already encountered a URL that used this favicon, use the ID we |
| 2366 // previously got. | 2370 // previously got. |
| 2367 new_id = found->second; | 2371 new_id = found->second; |
| 2368 } | 2372 } |
| 2369 // Add Icon mapping, and we don't care wheteher it suceeded or not. | 2373 // Add Icon mapping, and we don't care wheteher it suceeded or not. |
| 2370 thumbnail_db_->AddToTemporaryIconMappingTable(i->url(), new_id); | 2374 thumbnail_db_->AddToTemporaryIconMappingTable(i->url(), new_id); |
| 2371 } | 2375 } |
| 2372 } | 2376 } |
| 2373 #if defined(OS_ANDROID) | 2377 #if defined(OS_ANDROID) |
| 2374 // TODO (michaelbai): Add the unit test once AndroidProviderBackend is | 2378 // TODO (michaelbai): Add the unit test once AndroidProviderBackend is |
| 2375 // avaliable in HistoryBackend. | 2379 // avaliable in HistoryBackend. |
| 2376 db_->ClearAndroidURLRows(); | 2380 db_->ClearAndroidURLRows(); |
| 2377 #endif | 2381 #endif |
| 2378 | 2382 |
| 2379 // Rename the duplicate favicon and icon_mapping back table and recreate the | 2383 // Drop original favicon_bitmaps, favicons, and icon mapping tables and |
| 2380 // other tables. This will make the database consistent again. | 2384 // replace them with the duplicate tables. Recreate the other tables. This |
| 2381 thumbnail_db_->CommitTemporaryFaviconTable(); | 2385 // will make the database consistent again. |
| 2382 thumbnail_db_->CommitTemporaryIconMappingTable(); | 2386 thumbnail_db_->CommitTemporaryTables(); |
| 2383 | 2387 |
| 2384 thumbnail_db_->RecreateThumbnailTable(); | 2388 thumbnail_db_->RecreateThumbnailTable(); |
| 2385 | 2389 |
| 2386 // Vacuum to remove all the pages associated with the dropped tables. There | 2390 // Vacuum to remove all the pages associated with the dropped tables. There |
| 2387 // must be no transaction open on the table when we do this. We assume that | 2391 // must be no transaction open on the table when we do this. We assume that |
| 2388 // our long-running transaction is open, so we complete it and start it again. | 2392 // our long-running transaction is open, so we complete it and start it again. |
| 2389 DCHECK(thumbnail_db_->transaction_nesting() == 1); | 2393 DCHECK(thumbnail_db_->transaction_nesting() == 1); |
| 2390 thumbnail_db_->CommitTransaction(); | 2394 thumbnail_db_->CommitTransaction(); |
| 2391 thumbnail_db_->Vacuum(); | 2395 thumbnail_db_->Vacuum(); |
| 2392 thumbnail_db_->BeginTransaction(); | 2396 thumbnail_db_->BeginTransaction(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2459 } | 2463 } |
| 2460 } | 2464 } |
| 2461 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name | 2465 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name |
| 2462 TimeTicks::Now() - beginning_time); | 2466 TimeTicks::Now() - beginning_time); |
| 2463 return success; | 2467 return success; |
| 2464 } | 2468 } |
| 2465 | 2469 |
| 2466 bool HistoryBackend::GetFaviconFromDB(FaviconID favicon_id, | 2470 bool HistoryBackend::GetFaviconFromDB(FaviconID favicon_id, |
| 2467 FaviconData* favicon) { | 2471 FaviconData* favicon) { |
| 2468 Time last_updated; | 2472 Time last_updated; |
| 2469 scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes(); | 2473 scoped_refptr<base::RefCountedMemory> data; |
| 2470 | 2474 |
| 2471 if (!thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data->data(), | 2475 if (!thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data, |
| 2472 &favicon->icon_url, &favicon->icon_type)) | 2476 &favicon->icon_url, &favicon->icon_type)) |
| 2473 return false; | 2477 return false; |
| 2474 | 2478 |
| 2475 favicon->expired = (Time::Now() - last_updated) > | 2479 favicon->expired = (Time::Now() - last_updated) > |
| 2476 TimeDelta::FromDays(kFaviconRefetchDays); | 2480 TimeDelta::FromDays(kFaviconRefetchDays); |
| 2477 favicon->known_icon = true; | 2481 favicon->known_icon = true; |
| 2478 favicon->image_data = data; | 2482 favicon->image_data = data; |
| 2479 return true; | 2483 return true; |
| 2480 } | 2484 } |
| 2481 | 2485 |
| 2482 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { | 2486 void HistoryBackend::NotifyVisitObservers(const VisitRow& visit) { |
| 2483 BriefVisitInfo info; | 2487 BriefVisitInfo info; |
| 2484 info.url_id = visit.url_id; | 2488 info.url_id = visit.url_id; |
| 2485 info.time = visit.visit_time; | 2489 info.time = visit.visit_time; |
| 2486 info.transition = visit.transition; | 2490 info.transition = visit.transition; |
| 2487 // If we don't have a delegate yet during setup or shutdown, we will drop | 2491 // If we don't have a delegate yet during setup or shutdown, we will drop |
| 2488 // these notifications. | 2492 // these notifications. |
| 2489 if (delegate_.get()) | 2493 if (delegate_.get()) |
| 2490 delegate_->NotifyVisitDBObserversOnAddVisit(info); | 2494 delegate_->NotifyVisitDBObserversOnAddVisit(info); |
| 2491 } | 2495 } |
| 2492 | 2496 |
| 2493 } // namespace history | 2497 } // namespace history |
| OLD | NEW |