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

Unified Diff: chrome/renderer/favicon_helper.cc

Issue 11232068: Extract renderer-side favicon downloading code into separate helper class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: move UpdateFaviconURL code into helper Created 8 years, 2 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
« chrome/renderer/favicon_helper.h ('K') | « chrome/renderer/favicon_helper.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/favicon_helper.cc
diff --git a/chrome/renderer/favicon_helper.cc b/chrome/renderer/favicon_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6cb3b48c592c8f5f2e146a73fe8c6ee0ed249b73
--- /dev/null
+++ b/chrome/renderer/favicon_helper.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/favicon_helper.h"
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "chrome/common/favicon_url.h"
+#include "chrome/common/icon_messages.h"
+#include "content/public/renderer/render_view.h"
+#include "net/base/data_url.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
+#include "ui/gfx/favicon_size.h"
+#include "ui/gfx/size.h"
+#include "ui/gfx/skbitmap_operations.h"
+#include "webkit/glue/image_decoder.h"
+#include "webkit/glue/multi_resolution_image_resource_fetcher.h"
+#include "webkit/glue/webkit_glue.h"
+
+using WebKit::WebURLRequest;
+using webkit_glue::MultiResolutionImageResourceFetcher;
+
+FaviconHelper::FaviconHelper(content::RenderView* render_view)
+ : content::RenderViewObserver(render_view) {
+}
+
+FaviconHelper::~FaviconHelper() {
+}
+
+void FaviconHelper::SendUpdateFaviconURL(int32 routing_id,
+ int32 page_id,
+ const std::vector<FaviconURL>& urls) {
+ if (!urls.empty()) {
+ Send(new IconHostMsg_UpdateFaviconURL(routing_id, page_id, urls));
+ }
+}
+
+bool FaviconHelper::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(FaviconHelper, message)
+ IPC_MESSAGE_HANDLER(IconMsg_DownloadFavicon, OnDownloadFavicon)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+
+ return handled;
+}
+
+void FaviconHelper::OnDownloadFavicon(int id,
+ const GURL& image_url,
+ int image_size) {
+ bool data_image_failed = false;
+ if (image_url.SchemeIs("data")) {
+ SkBitmap data_image = ImageFromDataUrl(image_url);
+ data_image_failed = data_image.empty();
+ if (!data_image_failed) {
+ std::vector<SkBitmap> images(1, data_image);
+ Send(new IconHostMsg_DidDownloadFavicon(
+ routing_id(), id, image_url, false, image_size, images));
+ }
+ }
+
+ if (data_image_failed ||
+ !DownloadFavicon(id, image_url, image_size)) {
+ Send(new IconHostMsg_DidDownloadFavicon(
+ routing_id(), id, image_url, true, image_size,
+ std::vector<SkBitmap>()));
+ }
+}
+
+bool FaviconHelper::DownloadFavicon(int id,
+ const GURL& image_url,
+ int image_size) {
+ // Make sure webview was not shut down.
+ if (!render_view()->GetWebView())
+ return false;
+ // Create an image resource fetcher and assign it with a call back object.
+ image_fetchers_.push_back(linked_ptr<MultiResolutionImageResourceFetcher>(
+ new MultiResolutionImageResourceFetcher(
+ image_url, render_view()->GetWebView()->mainFrame(), id,
+ WebURLRequest::TargetIsFavicon,
+ base::Bind(&FaviconHelper::DidDownloadFavicon,
+ base::Unretained(this), image_size))));
+ return true;
+}
+
+void FaviconHelper::DidDownloadFavicon(
+ int requested_size,
+ MultiResolutionImageResourceFetcher* fetcher,
+ const std::vector<SkBitmap>& images) {
+ // Notify requester of image download status.
+ Send(new IconHostMsg_DidDownloadFavicon(routing_id(),
+ fetcher->id(),
+ fetcher->image_url(),
+ images.empty(),
+ requested_size,
+ images));
+
+ // Remove the image fetcher from our pending list. We're in the callback from
+ // MultiResolutionImageResourceFetcher, best to delay deletion.
+ ImageResourceFetcherList::iterator iter;
+ for (iter = image_fetchers_.begin(); iter != image_fetchers_.end(); ++iter) {
joth 2012/10/24 22:02:23 fwiw, if image_fetchers_ is ScopedVector I think w
Cait (Slow) 2012/10/25 20:29:23 Done.
+ if (iter->get() == fetcher) {
+ iter->release();
+ image_fetchers_.erase(iter);
+ break;
+ }
+ }
+ MessageLoop::current()->DeleteSoon(FROM_HERE, fetcher);
+}
+
+SkBitmap FaviconHelper::ImageFromDataUrl(const GURL& url) const {
+ std::string mime_type, char_set, data;
+ if (net::DataURL::Parse(url, &mime_type, &char_set, &data) && !data.empty()) {
+ // Decode the favicon using WebKit's image decoder.
+ webkit_glue::ImageDecoder decoder(
+ gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize));
+ const unsigned char* src_data =
+ reinterpret_cast<const unsigned char*>(&data[0]);
+
+ return decoder.Decode(src_data, data.size());
+ }
+ return SkBitmap();
+}
« chrome/renderer/favicon_helper.h ('K') | « chrome/renderer/favicon_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698