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

Unified Diff: chrome/browser/ui/intents/web_intent_picker_controller.cc

Issue 9430025: [Web Intents] WebIntentsPickerController will now fetch icon for suggested extensions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: favicon->icon Created 8 years, 10 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/ui/intents/web_intent_picker_controller.cc
diff --git a/chrome/browser/ui/intents/web_intent_picker_controller.cc b/chrome/browser/ui/intents/web_intent_picker_controller.cc
index fbe21840679e0917dff040c7dda430bb257b33c8..1d3f326b568ce945bb55ea0f6f5b1102cca86019 100644
--- a/chrome/browser/ui/intents/web_intent_picker_controller.cc
+++ b/chrome/browser/ui/intents/web_intent_picker_controller.cc
@@ -23,10 +23,16 @@
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/browser/intents/intent_injector.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_intents_dispatcher.h"
+#include "content/public/common/url_fetcher.h"
+#include "content/public/common/url_fetcher_delegate.h"
+#include "net/base/load_flags.h"
+#include "skia/ext/image_operations.h"
#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/favicon_size.h"
#include "ui/gfx/image/image.h"
#include "webkit/glue/web_intent_service_data.h"
@@ -60,6 +66,25 @@ WebIntentPickerModel::Disposition ConvertDisposition(
}
}
+class URLFetcherTrampoline : public content::URLFetcherDelegate {
+ public:
+ typedef base::Callback<void(const content::URLFetcher* source)> Callback;
+
+ explicit URLFetcherTrampoline(const Callback& callback)
+ : callback_(callback) {}
+ ~URLFetcherTrampoline() {}
+
+ // content::URLFetcherDelegate implementation.
+ virtual void OnURLFetchComplete(const content::URLFetcher* source) OVERRIDE {
+ callback_.Run(source);
+ delete source;
+ delete this;
+ }
+
+ private:
+ Callback callback_;
+};
+
} // namespace
WebIntentPickerController::WebIntentPickerController(
@@ -285,6 +310,9 @@ void WebIntentPickerController::OnFaviconDataAvailable(
void WebIntentPickerController::OnCWSIntentServicesAvailable(
const CWSIntentsRegistry::IntentExtensionList& extensions) {
+ net::URLRequestContextGetter* context =
+ wrapper_->profile()->GetRequestContext();
+
for (size_t i = 0; i < extensions.size(); ++i) {
const CWSIntentsRegistry::IntentExtensionInfo& info = extensions[i];
picker_model_->AddSuggestedExtension(
@@ -292,12 +320,92 @@ void WebIntentPickerController::OnCWSIntentServicesAvailable(
info.id,
info.average_rating);
- // TODO(binji): Fetch extension icon.
+ pending_async_count_++;
+ content::URLFetcher* icon_url_fetcher = content::URLFetcher::Create(
+ 0,
+ info.icon_url,
+ content::URLFetcher::GET,
+ new URLFetcherTrampoline(
+ base::Bind(
+ &WebIntentPickerController::OnExtensionIconURLFetchComplete,
+ weak_ptr_factory_.GetWeakPtr(), info.id)));
+
+ icon_url_fetcher->SetLoadFlags(
+ net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
+ icon_url_fetcher->SetRequestContext(context);
+ icon_url_fetcher->Start();
}
AsyncOperationFinished();
}
+void WebIntentPickerController::OnExtensionIconURLFetchComplete(
Greg Billock 2012/02/23 18:38:34 This'll get called by the fetcher thread, right? I
binji 2012/02/23 19:06:13 AFAIK this is called back on the UI thread, so it
+ const string16& extension_id, const content::URLFetcher* source) {
+ if (source->GetResponseCode() != 200)
+ return;
Greg Billock 2012/02/23 18:38:34 Need to AsyncOperationFinished here?
binji 2012/02/23 19:06:13 Done.
+
+ scoped_ptr<std::string> response(new std::string());
Greg Billock 2012/02/23 18:38:34 Can kill inner "()"
binji 2012/02/23 19:06:13 Done.
+ if (source->GetResponseAsString(response.get())) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ // Decode PNG and resize on worker thread.
+ content::BrowserThread::PostBlockingPoolTask(
Greg Billock 2012/02/23 18:38:34 These cascades are why the frontends ended up usin
binji 2012/02/23 19:06:13 Agreed. Though I think it's not too hard to follow
+ FROM_HERE,
+ base::Bind(&DecodeExtensionIconAndResize,
+ base::Passed(&response),
+ base::Bind(
+ &WebIntentPickerController::OnExtensionIconAvailable,
+ weak_ptr_factory_.GetWeakPtr(),
+ extension_id),
+ base::Bind(
+ &WebIntentPickerController::OnExtensionIconUnavailable,
+ weak_ptr_factory_.GetWeakPtr(),
+ extension_id)));
+ } else {
+ AsyncOperationFinished();
+ }
+}
+
+// static
+void WebIntentPickerController::DecodeExtensionIconAndResize(
+ scoped_ptr<std::string> icon_response,
+ const ExtensionIconAvailableCallback& callback,
+ const base::Closure& unavailable_callback) {
+ SkBitmap icon_bitmap;
+ if (gfx::PNGCodec::Decode(
+ reinterpret_cast<const unsigned char*>(icon_response->data()),
+ icon_response->length(),
+ &icon_bitmap)) {
+ SkBitmap resized_icon = skia::ImageOperations::Resize(
Greg Billock 2012/02/23 18:38:34 Is this doing an extra image copy?
binji 2012/02/23 19:06:13 Yes, it doesn't resize in-place.
+ icon_bitmap,
+ skia::ImageOperations::RESIZE_BEST,
+ gfx::kFaviconSize, gfx::kFaviconSize);
+ gfx::Image icon_image(new SkBitmap(resized_icon));
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(callback, icon_image));
Greg Billock 2012/02/23 18:38:34 So gfx::Image is pointer-ish and cool to pass like
binji 2012/02/23 19:06:13 Yes, gfx::Image has internal refcounted storage.
+ } else {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ unavailable_callback);
+ }
+}
+
+void WebIntentPickerController::OnExtensionIconAvailable(
+ const string16& extension_id,
+ const gfx::Image& icon_image) {
+ picker_model_->SetSuggestedExtensionIconWithId(extension_id, icon_image);
+ AsyncOperationFinished();
+}
+
+void WebIntentPickerController::OnExtensionIconUnavailable(
+ const string16& extension_id) {
+ AsyncOperationFinished();
+}
+
void WebIntentPickerController::AsyncOperationFinished() {
if (--pending_async_count_ == 0) {
Greg Billock 2012/02/23 18:38:34 So we don't need a mutex here because Decode() is
binji 2012/02/23 19:06:13 This callback is only used to notify a test that a
picker_->OnPendingAsyncCompleted();

Powered by Google App Engine
This is Rietveld 408576698