Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4643)

Unified Diff: chrome/browser/history/history_backend.cc

Issue 10802066: Adds support for saving favicon size into history database. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/history/history_backend.cc
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index 7488b353720ba31d2142d85fb21626aec5dbb3e5..e5e7420254171b6db28dba58b0242eaa37295ffa 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -36,6 +36,7 @@
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "ui/gfx/favicon_size.h"
#if defined(OS_ANDROID)
#include "chrome/browser/history/android/android_provider_backend.h"
@@ -94,6 +95,9 @@ static const int kMaxRedirectCount = 32;
// and is archived.
static const int kArchiveDaysThreshold = 90;
+// The maximum number of favicon bitmaps stored for a single page.
+const size_t kMaxFaviconsPerPage = 30;
+
// Converts from PageUsageData to MostVisitedURL. |redirects| is a
// list of redirects for this URL. Empty list means no redirects.
MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data,
@@ -1773,16 +1777,20 @@ bool HistoryBackend::GetThumbnailFromOlderRedirect(
void HistoryBackend::GetFavicon(scoped_refptr<GetFaviconRequest> request,
const GURL& icon_url,
+ const gfx::Size& pixel_size,
int icon_types) {
- UpdateFaviconMappingAndFetchImpl(NULL, icon_url, request, icon_types);
+ UpdateFaviconMappingAndFetchImpl(NULL, icon_url, request, pixel_size,
+ icon_types);
}
void HistoryBackend::UpdateFaviconMappingAndFetch(
scoped_refptr<GetFaviconRequest> request,
const GURL& page_url,
const GURL& icon_url,
+ const gfx::Size& pixel_size,
IconType icon_type) {
- UpdateFaviconMappingAndFetchImpl(&page_url, icon_url, request, icon_type);
+ UpdateFaviconMappingAndFetchImpl(&page_url, icon_url, request, pixel_size,
+ icon_type);
}
void HistoryBackend::SetFaviconOutOfDateForPage(const GURL& page_url) {
@@ -1824,16 +1832,24 @@ void HistoryBackend::SetImportedFavicons(
std::set<GURL> favicons_changed;
for (size_t i = 0; i < favicon_usage.size(); i++) {
- FaviconID favicon_id = thumbnail_db_->GetFaviconIDForFaviconURL(
- favicon_usage[i].favicon_url, history::FAVICON, NULL);
- if (!favicon_id) {
+ std::vector<FaviconIDAndSize> favicon_id_size_listing;
+ thumbnail_db_->GetFaviconIDsForFaviconURL(favicon_usage[i].favicon_url,
+ history::FAVICON, &favicon_id_size_listing);
+ if (favicon_id_size_listing.empty()) {
// This favicon doesn't exist yet, so we create it using the given data.
- favicon_id = thumbnail_db_->AddFavicon(favicon_usage[i].favicon_url,
- history::FAVICON);
+ gfx::Size default_size =
+ gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
+ FaviconID favicon_id = thumbnail_db_->AddFavicon(
+ favicon_usage[i].favicon_url, default_size, history::FAVICON);
if (!favicon_id)
continue; // Unable to add the favicon.
thumbnail_db_->SetFavicon(favicon_id,
new base::RefCountedBytes(favicon_usage[i].png_data), now);
+
+ FaviconIDAndSize favicon_id_size;
+ favicon_id_size.icon_id = favicon_id;
+ favicon_id_size.icon_size = default_size;
+ favicon_id_size_listing.push_back(favicon_id_size);
}
// Save the mapping from all the URLs to the favicon.
@@ -1854,14 +1870,25 @@ void HistoryBackend::SetImportedFavicons(
url_info.set_last_visit(base::Time());
url_info.set_hidden(false);
db_->AddURL(url_info);
- thumbnail_db_->AddIconMapping(*url, favicon_id);
+
+ for (std::vector<FaviconIDAndSize>::iterator favicon_id_size =
+ favicon_id_size_listing.begin();
+ favicon_id_size != favicon_id_size_listing.end();
+ ++favicon_id_size) {
+ thumbnail_db_->AddIconMapping(*url, favicon_id_size->icon_id);
+ }
favicons_changed.insert(*url);
}
} else {
- if (!thumbnail_db_->GetIconMappingForPageURL(*url, FAVICON, NULL)) {
+ if (!thumbnail_db_->GetIconMappingsForPageURL(*url, FAVICON, NULL)) {
// URL is present in history, update the favicon *only* if it is not
// set already.
- thumbnail_db_->AddIconMapping(*url, favicon_id);
+ for (std::vector<FaviconIDAndSize>::iterator favicon_id_size =
+ favicon_id_size_listing.begin();
+ favicon_id_size != favicon_id_size_listing.end();
+ ++favicon_id_size) {
+ thumbnail_db_->AddIconMapping(*url, favicon_id_size->icon_id);
+ }
favicons_changed.insert(*url);
}
}
@@ -1881,6 +1908,7 @@ void HistoryBackend::UpdateFaviconMappingAndFetchImpl(
const GURL* page_url,
const GURL& icon_url,
scoped_refptr<GetFaviconRequest> request,
+ const gfx::Size& pixel_size,
int icon_types) {
// Check only a single type was given when the page_url was specified.
DCHECK(!page_url || (page_url && (icon_types == FAVICON ||
@@ -1892,22 +1920,15 @@ void HistoryBackend::UpdateFaviconMappingAndFetchImpl(
FaviconData favicon;
if (thumbnail_db_.get()) {
- const FaviconID favicon_id =
- thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, icon_types, &favicon.icon_type);
+ std::vector<FaviconIDAndSize> favicon_id_size_listing;
+ thumbnail_db_->GetFaviconIDsForFaviconURL(icon_url, icon_types,
+ &favicon_id_size_listing);
+ FaviconID favicon_id = GetFaviconID(favicon_id_size_listing, pixel_size);
if (favicon_id) {
- scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes();
- favicon.known_icon = true;
- Time last_updated;
- if (thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data->data(),
- NULL, NULL)) {
- favicon.expired = (Time::Now() - last_updated) >
- TimeDelta::FromDays(kFaviconRefetchDays);
- favicon.image_data = data;
+ GetFaviconFromDB(favicon_id, &favicon);
+ if (page_url) {
+ SetFaviconMapping(*page_url, favicon_id, pixel_size, favicon.icon_type);
}
-
- if (page_url)
- SetFaviconMapping(*page_url, favicon_id, favicon.icon_type);
}
// else case, haven't cached entry yet. Caller is responsible for
// downloading the favicon and invoking SetFavicon.
@@ -1915,9 +1936,36 @@ void HistoryBackend::UpdateFaviconMappingAndFetchImpl(
request->ForwardResult(request->handle(), favicon);
}
+FaviconID HistoryBackend::GetFaviconID(
+ const std::vector<FaviconIDAndSize>& favicon_id_size_listing,
+ const gfx::Size& desired_pixel_size) const {
+ // Give preference to favicon sizes which will result in downscaling rather
+ // than upscaling.
+ FaviconID closest_favicon_id = 0;
+ gfx::Size closest_pixel_size;
+ for (size_t i = 0; i < favicon_id_size_listing.size(); ++i) {
+ gfx::Size size = favicon_id_size_listing[i].icon_size;
+ if (closest_pixel_size.GetArea() < desired_pixel_size.GetArea() &&
stevenjb 2012/08/01 00:00:31 Area may not be the best method for comparison. Fo
pkotwicz 2012/08/02 19:47:52 Agree
+ size.GetArea() > closest_pixel_size.GetArea()) {
+ closest_favicon_id = favicon_id_size_listing[i].icon_id;
+ closest_pixel_size = size;
+ } else if (closest_pixel_size.GetArea() > desired_pixel_size.GetArea() &&
+ size.GetArea() < closest_pixel_size.GetArea() &&
+ size.GetArea() >= desired_pixel_size.GetArea()) {
+ closest_favicon_id = favicon_id_size_listing[i].icon_id;
+ closest_pixel_size = size;
+ }
+
+ if (closest_pixel_size == desired_pixel_size)
+ break;
+ }
+ return closest_favicon_id;
+}
+
void HistoryBackend::GetFaviconForURL(
scoped_refptr<GetFaviconRequest> request,
const GURL& page_url,
+ const gfx::Size& pixel_size,
int icon_types) {
if (request->canceled())
return;
@@ -1925,7 +1973,7 @@ void HistoryBackend::GetFaviconForURL(
FaviconData favicon;
// Get the favicon from DB.
- GetFaviconFromDB(page_url, icon_types, &favicon);
+ GetFaviconFromDB(page_url, pixel_size, icon_types, &favicon);
request->ForwardResult(request->handle(), favicon);
}
@@ -1944,24 +1992,38 @@ void HistoryBackend::SetFavicon(
const GURL& page_url,
const GURL& icon_url,
scoped_refptr<base::RefCountedMemory> data,
+ const gfx::Size& requested_size,
IconType icon_type) {
+ // For M22, store |requested_size| as the favicon's pixel size into the
+ // favicon database table.
+ // TODO(pkotwicz): Fix this.
DCHECK(data.get());
if (!thumbnail_db_.get() || !db_.get())
return;
- FaviconID id = thumbnail_db_->GetFaviconIDForFaviconURL(
- icon_url, icon_type, NULL);
- if (!id)
- id = thumbnail_db_->AddFavicon(icon_url, icon_type);
+ std::vector<FaviconIDAndSize> favicon_id_size_listing;
+ thumbnail_db_->GetFaviconIDsForFaviconURL(icon_url, icon_type,
+ &favicon_id_size_listing);
+ FaviconID id = 0;
+ for (size_t i = 0; i < favicon_id_size_listing.size(); ++i) {
+ if (favicon_id_size_listing[i].icon_size == requested_size) {
+ id = favicon_id_size_listing[i].icon_id;
+ break;
+ }
+ }
+
+ if (!id)
+ id = thumbnail_db_->AddFavicon(icon_url, requested_size, icon_type);
// Set the image data.
thumbnail_db_->SetFavicon(id, data, Time::Now());
- SetFaviconMapping(page_url, id, icon_type);
+ SetFaviconMapping(page_url, id, requested_size, icon_type);
}
void HistoryBackend::SetFaviconMapping(const GURL& page_url,
FaviconID id,
+ const gfx::Size& pixel_size,
IconType icon_type) {
if (!thumbnail_db_.get())
return;
@@ -1990,7 +2052,7 @@ void HistoryBackend::SetFaviconMapping(const GURL& page_url,
for (history::RedirectList::const_iterator i(redirects->begin());
i != redirects->end(); ++i) {
FaviconID replaced_id;
- if (AddOrUpdateIconMapping(*i, id, icon_type, &replaced_id)) {
+ if (AddOrUpdateIconMapping(*i, id, pixel_size, icon_type, &replaced_id)) {
// The page's favicon ID changed. This means that the one we just
// changed from could have been orphaned, and we need to re-check it.
// This is not super fast, but this case will get triggered rarely,
@@ -2014,6 +2076,7 @@ void HistoryBackend::SetFaviconMapping(const GURL& page_url,
bool HistoryBackend::AddOrUpdateIconMapping(const GURL& page_url,
FaviconID id,
+ const gfx::Size& pixel_size,
IconType icon_type,
FaviconID* replaced_icon) {
*replaced_icon = 0;
@@ -2025,26 +2088,41 @@ bool HistoryBackend::AddOrUpdateIconMapping(const GURL& page_url,
}
// Iterate all matched icon mappings,
// a. If the given icon id and matched icon id are same, return.
- // b. If the given icon type and matched icon type are same, but icon id
- // are not, update the IconMapping.
- // c. If the given icon_type and matched icon type are not same, but
- // either of them is ICON_TOUCH or ICON_PRECOMPOSED_TOUCH, update the
- // IconMapping.
- // d. Otherwise add a icon mapping.
+ // b. If the given icon size and the matched icon size are the same and
+ // either:
+ // i. the given icon type and the matched icon type are the same.
+ // ii. the given icon type and matched icon type are not the same
+ // but either of them is ICON_TOUCH or ICON_PRECOMPOSED_TOUCH.
stevenjb 2012/08/01 00:00:31 Do we care about differentiating between touch and
pkotwicz 2012/08/02 19:47:52 I'll look into this.
+ // update the IconMapping.
+ // c. If there are no matches, but the number of mappings for page url
+ // has exceeded kMaxFaviconsPerPage, update an arbitrary mapping. This
+ // is a last line of defense and this property should be enforced
+ // elsewhere as well.
stevenjb 2012/08/01 00:00:31 This seems a bit arbitrary. Have we considered def
pkotwicz 2012/08/02 19:47:52 We are actually going to be doing this too. It sti
+ // d. Otherwise add an icon mapping.
+
for (std::vector<IconMapping>::iterator m = icon_mappings.begin();
m != icon_mappings.end(); ++m) {
if (m->icon_id == id)
// The mapping is already there.
return false;
- if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) ||
- (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) ||
- (icon_type == m->icon_type)) {
- thumbnail_db_->UpdateIconMapping(m->mapping_id, id);
- *replaced_icon = m->icon_id;
- return true;
+ if (pixel_size == m->icon_pixel_size) {
+ if ((icon_type == TOUCH_ICON && m->icon_type == TOUCH_PRECOMPOSED_ICON) ||
+ (icon_type == TOUCH_PRECOMPOSED_ICON && m->icon_type == TOUCH_ICON) ||
+ (icon_type == m->icon_type)) {
+ thumbnail_db_->UpdateIconMapping(m->mapping_id, id);
+ *replaced_icon = m->icon_id;
+ return true;
+ }
}
}
+
+ if (icon_mappings.size() >= kMaxFaviconsPerPage) {
+ thumbnail_db_->UpdateIconMapping(icon_mappings[0].mapping_id, id);
+ *replaced_icon = icon_mappings[0].icon_id;
stevenjb 2012/08/01 00:00:31 Shouldn't this logic be in AddIconMapping? It's no
pkotwicz 2012/08/02 19:47:52 I would rather not add extra SQL queries to AddIco
+ return true;
+ }
+
thumbnail_db_->AddIconMapping(page_url, id);
return true;
}
@@ -2434,6 +2512,7 @@ BookmarkService* HistoryBackend::GetBookmarkService() {
bool HistoryBackend::GetFaviconFromDB(
const GURL& page_url,
+ const gfx::Size& pixel_size,
int icon_types,
FaviconData* favicon) {
DCHECK(favicon);
@@ -2446,17 +2525,20 @@ bool HistoryBackend::GetFaviconFromDB(
TimeTicks beginning_time = TimeTicks::Now();
std::vector<IconMapping> icon_mappings;
- // Iterate over the known icons looking for one that includes one of the
- // requested types.
- if (thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) {
+ if (thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_types,
+ &icon_mappings)) {
+ std::vector<FaviconIDAndSize> favicon_id_size_listing;
for (std::vector<IconMapping>::iterator i = icon_mappings.begin();
i != icon_mappings.end(); ++i) {
- if ((i->icon_type & icon_types) &&
- GetFaviconFromDB(i->icon_id, favicon)) {
- success = true;
- break;
- }
+ FaviconIDAndSize favicon_id_size;
+ favicon_id_size.icon_id = i->icon_id;
+ favicon_id_size.icon_size = i->icon_pixel_size;
+ favicon_id_size_listing.push_back(favicon_id_size);
}
+ FaviconID favicon_id = GetFaviconID(favicon_id_size_listing, pixel_size);
+
+ if (favicon_id && GetFaviconFromDB(favicon_id, favicon))
+ success = true;
}
UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name
TimeTicks::Now() - beginning_time);
@@ -2468,14 +2550,14 @@ bool HistoryBackend::GetFaviconFromDB(FaviconID favicon_id,
Time last_updated;
scoped_refptr<base::RefCountedBytes> data = new base::RefCountedBytes();
+ favicon->known_icon = true;
if (!thumbnail_db_->GetFavicon(favicon_id, &last_updated, &data->data(),
- &favicon->icon_url, &favicon->icon_type))
+ &favicon->icon_url, &favicon->requested_size, &favicon->icon_type))
return false;
favicon->expired = (Time::Now() - last_updated) >
TimeDelta::FromDays(kFaviconRefetchDays);
- favicon->known_icon = true;
- favicon->image_data = data;
+ favicon->bitmap_data = data;
return true;
}

Powered by Google App Engine
This is Rietveld 408576698