summaryrefslogtreecommitdiffstats
path: root/chrome/browser/favicon/favicon_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/favicon/favicon_service.cc')
-rw-r--r--chrome/browser/favicon/favicon_service.cc239
1 files changed, 217 insertions, 22 deletions
diff --git a/chrome/browser/favicon/favicon_service.cc b/chrome/browser/favicon/favicon_service.cc
index ff3d6e5..ec34ed1 100644
--- a/chrome/browser/favicon/favicon_service.cc
+++ b/chrome/browser/favicon/favicon_service.cc
@@ -4,21 +4,69 @@
#include "chrome/browser/favicon/favicon_service.h"
+#include "chrome/browser/favicon/select_favicon_frames.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/history_backend.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/common/url_constants.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/image/image_skia.h"
FaviconService::FaviconService(HistoryService* history_service)
: history_service_(history_service) {
}
+FaviconService::Handle FaviconService::GetFaviconImage(
+ const GURL& icon_url,
+ history::IconType icon_type,
+ int desired_size_in_dip,
+ CancelableRequestConsumerBase* consumer,
+ const FaviconImageCallback& callback) {
+ GetFaviconRequest* request = new GetFaviconRequest(base::Bind(
+ &FaviconService::GetFaviconImageCallback,
+ base::Unretained(this),
+ desired_size_in_dip,
+ callback));
+ AddRequest(request, consumer);
+ // TODO(pkotwicz): Pass in desired size and scale factors.
+ if (history_service_)
+ history_service_->GetFavicon(request, icon_url, icon_type);
+ else
+ ForwardEmptyResultAsync(request);
+ return request->handle();
+}
+
+FaviconService::Handle FaviconService::GetRawFavicon(
+ const GURL& icon_url,
+ history::IconType icon_type,
+ int desired_size_in_dip,
+ ui::ScaleFactor desired_scale_factor,
+ CancelableRequestConsumerBase* consumer,
+ const FaviconRawCallback& callback) {
+ GetFaviconRequest* request = new GetFaviconRequest(base::Bind(
+ &FaviconService::GetRawFaviconCallback,
+ base::Unretained(this),
+ desired_size_in_dip,
+ desired_scale_factor,
+ callback));
+ AddRequest(request, consumer);
+ // TODO(pkotwicz): Pass in desired size and scale factor.
+ if (history_service_)
+ history_service_->GetFavicon(request, icon_url, icon_type);
+ else
+ ForwardEmptyResultAsync(request);
+ return request->handle();
+}
+
FaviconService::Handle FaviconService::GetFavicon(
const GURL& icon_url,
history::IconType icon_type,
+ int desired_size_in_dip,
+ const std::vector<ui::ScaleFactor>& desired_scale_factors,
CancelableRequestConsumerBase* consumer,
- const FaviconDataCallback& callback) {
+ const FaviconResultsCallback& callback) {
GetFaviconRequest* request = new GetFaviconRequest(callback);
AddRequest(request, consumer);
if (history_service_)
@@ -33,7 +81,7 @@ FaviconService::Handle FaviconService::UpdateFaviconMappingAndFetch(
const GURL& icon_url,
history::IconType icon_type,
CancelableRequestConsumerBase* consumer,
- const FaviconDataCallback& callback) {
+ const FaviconResultsCallback& callback) {
GetFaviconRequest* request = new GetFaviconRequest(callback);
AddRequest(request, consumer);
if (history_service_)
@@ -44,37 +92,75 @@ FaviconService::Handle FaviconService::UpdateFaviconMappingAndFetch(
return request->handle();
}
+FaviconService::Handle FaviconService::GetFaviconImageForURL(
+ Profile* profile,
+ const GURL& page_url,
+ int icon_types,
+ int desired_size_in_dip,
+ CancelableRequestConsumerBase* consumer,
+ const FaviconImageCallback& callback) {
+ GetFaviconRequest* request = new GetFaviconRequest(base::Bind(
+ &FaviconService::GetFaviconImageCallback,
+ base::Unretained(this),
+ desired_size_in_dip,
+ callback));
+
+ std::vector<ui::ScaleFactor> desired_scale_factors =
+ ui::GetSupportedScaleFactors();
+ return GetFaviconForURLImpl(profile, page_url, icon_types,
+ desired_size_in_dip, desired_scale_factors, consumer, request);
+}
+
+FaviconService::Handle FaviconService::GetRawFaviconForURL(
+ Profile* profile,
+ const GURL& page_url,
+ int icon_types,
+ int desired_size_in_dip,
+ ui::ScaleFactor desired_scale_factor,
+ CancelableRequestConsumerBase* consumer,
+ const FaviconRawCallback& callback) {
+ GetFaviconRequest* request = new GetFaviconRequest(base::Bind(
+ &FaviconService::GetRawFaviconCallback,
+ base::Unretained(this),
+ desired_size_in_dip,
+ desired_scale_factor,
+ callback));
+
+ std::vector<ui::ScaleFactor> desired_scale_factors;
+ desired_scale_factors.push_back(desired_scale_factor);
+ return GetFaviconForURLImpl(profile, page_url, icon_types,
+ desired_size_in_dip, desired_scale_factors, consumer, request);
+}
+
FaviconService::Handle FaviconService::GetFaviconForURL(
Profile* profile,
const GURL& page_url,
int icon_types,
+ int desired_size_in_dip,
+ const std::vector<ui::ScaleFactor>& desired_scale_factors,
CancelableRequestConsumerBase* consumer,
- const FaviconDataCallback& callback) {
+ const FaviconResultsCallback& callback) {
GetFaviconRequest* request = new GetFaviconRequest(callback);
- AddRequest(request, consumer);
- FaviconService::Handle handle = request->handle();
- if (page_url.SchemeIs(chrome::kChromeUIScheme) ||
- page_url.SchemeIs(chrome::kExtensionScheme)) {
- ChromeWebUIControllerFactory::GetInstance()->GetFaviconForURL(
- profile, request, page_url);
- } else {
- if (history_service_)
- history_service_->GetFaviconForURL(request, page_url, icon_types);
- else
- ForwardEmptyResultAsync(request);
- }
- return handle;
+ return GetFaviconForURLImpl(profile, page_url, icon_types,
+ desired_size_in_dip, desired_scale_factors, consumer, request);
}
-// Requests the favicon for |favicon_id|. The |consumer| is notified when the
-// bits have been fetched.
-FaviconService::Handle FaviconService::GetFaviconForID(
+FaviconService::Handle FaviconService::GetRawFaviconForID(
history::FaviconID favicon_id,
+ int desired_size_in_dip,
+ ui::ScaleFactor desired_scale_factor,
CancelableRequestConsumerBase* consumer,
- const FaviconDataCallback& callback) {
- GetFaviconRequest* request = new GetFaviconRequest(callback);
+ const FaviconRawCallback& callback) {
+ GetFaviconRequest* request = new GetFaviconRequest(base::Bind(
+ &FaviconService::GetRawFaviconCallback,
+ base::Unretained(this),
+ desired_size_in_dip,
+ desired_scale_factor,
+ callback));
+
AddRequest(request, consumer);
FaviconService::Handle handle = request->handle();
+ // TODO(pkotwicz): Pass in desired size and scale factor.
if (history_service_)
history_service_->GetFaviconForID(request, favicon_id);
else
@@ -112,6 +198,115 @@ void FaviconService::SetFavicon(const GURL& page_url,
FaviconService::~FaviconService() {
}
+FaviconService::Handle FaviconService::GetFaviconForURLImpl(
+ Profile* profile,
+ const GURL& page_url,
+ int icon_types,
+ int desired_size_in_dip,
+ const std::vector<ui::ScaleFactor>& desired_scale_factors,
+ CancelableRequestConsumerBase* consumer,
+ GetFaviconRequest* request) {
+ AddRequest(request, consumer);
+ FaviconService::Handle handle = request->handle();
+ if (page_url.SchemeIs(chrome::kChromeUIScheme) ||
+ page_url.SchemeIs(chrome::kExtensionScheme)) {
+ // TODO(pkotwicz): Pass in desired size and desired scale factors.
+ ChromeWebUIControllerFactory::GetInstance()->GetFaviconForURL(
+ profile, request, page_url);
+ } else {
+ // TODO(pkotwicz): Pass in desired size and desired scale factors.
+ if (history_service_)
+ history_service_->GetFaviconForURL(request, page_url, icon_types);
+ else
+ ForwardEmptyResultAsync(request);
+ }
+ return handle;
+}
+
+void FaviconService::GetFaviconImageCallback(
+ int desired_size_in_dip,
+ FaviconImageCallback callback,
+ Handle handle,
+ std::vector<history::FaviconBitmapResult> favicon_bitmap_results,
+ history::IconURLSizesMap icon_url_sizes_map) {
+ std::vector<SkBitmap> sk_bitmaps;
+ for (size_t i = 0; i < favicon_bitmap_results.size(); ++i) {
+ if (favicon_bitmap_results[i].is_valid()) {
+ scoped_refptr<base::RefCountedMemory> bitmap_data =
+ favicon_bitmap_results[i].bitmap_data;
+ SkBitmap out_bitmap;
+ if (gfx::PNGCodec::Decode(bitmap_data->front(), bitmap_data->size(),
+ &out_bitmap)) {
+ sk_bitmaps.push_back(out_bitmap);
+ }
+ }
+ }
+ history::FaviconImageResult image_result;
+ image_result.image = gfx::Image(SelectFaviconFrames(
+ sk_bitmaps, ui::GetSupportedScaleFactors(), desired_size_in_dip, NULL));
+ image_result.icon_url = favicon_bitmap_results.empty() ?
+ GURL() : favicon_bitmap_results[0].icon_url;
+
+ callback.Run(handle, image_result);
+}
+
+void FaviconService::GetRawFaviconCallback(
+ int desired_size_in_dip,
+ ui::ScaleFactor desired_scale_factor,
+ FaviconRawCallback callback,
+ Handle handle,
+ std::vector<history::FaviconBitmapResult> favicon_bitmap_results,
+ history::IconURLSizesMap icon_url_sizes_map) {
+ if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid()) {
+ callback.Run(handle, history::FaviconBitmapResult());
+ return;
+ }
+
+ DCHECK_EQ(1u, favicon_bitmap_results.size());
+ history::FaviconBitmapResult bitmap_result = favicon_bitmap_results[0];
+
+ // If history bitmap is already desired pixel size, return early.
+ float desired_scale = ui::GetScaleFactorScale(desired_scale_factor);
+ int desired_edge_width_in_pixel = static_cast<int>(
+ desired_size_in_dip * desired_scale + 0.5f);
+ gfx::Size desired_size_in_pixel(desired_edge_width_in_pixel,
+ desired_edge_width_in_pixel);
+ if (bitmap_result.pixel_size == desired_size_in_pixel) {
+ callback.Run(handle, bitmap_result);
+ return;
+ }
+
+ // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then
+ // convert back.
+ SkBitmap bitmap;
+ if (!gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(),
+ bitmap_result.bitmap_data->size(),
+ &bitmap)) {
+ callback.Run(handle, history::FaviconBitmapResult());
+ return;
+ }
+
+ std::vector<SkBitmap> bitmaps;
+ bitmaps.push_back(bitmap);
+ std::vector<ui::ScaleFactor> desired_scale_factors;
+ desired_scale_factors.push_back(desired_scale_factor);
+ gfx::ImageSkia resized_image = SelectFaviconFrames(bitmaps,
+ desired_scale_factors, desired_size_in_dip, NULL);
+
+ std::vector<unsigned char> resized_bitmap_data;
+ if (!gfx::PNGCodec::EncodeBGRASkBitmap(*resized_image.bitmap(), false,
+ &resized_bitmap_data)) {
+ callback.Run(handle, history::FaviconBitmapResult());
+ return;
+ }
+
+ bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector(
+ &resized_bitmap_data);
+ callback.Run(handle, bitmap_result);
+}
+
void FaviconService::ForwardEmptyResultAsync(GetFaviconRequest* request) {
- request->ForwardResultAsync(request->handle(), history::FaviconData());
+ request->ForwardResultAsync(request->handle(),
+ std::vector<history::FaviconBitmapResult>(),
+ history::IconURLSizesMap());
}