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

Side by Side 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: . 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/ui/intents/web_intent_picker_controller.h" 5 #include "chrome/browser/ui/intents/web_intent_picker_controller.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "chrome/browser/ui/browser.h" 11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/favicon/favicon_service.h" 12 #include "chrome/browser/favicon/favicon_service.h"
13 #include "chrome/browser/intents/web_intents_registry_factory.h" 13 #include "chrome/browser/intents/web_intents_registry_factory.h"
14 #include "chrome/browser/intents/cws_intents_registry_factory.h" 14 #include "chrome/browser/intents/cws_intents_registry_factory.h"
15 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/tab_contents/tab_util.h" 16 #include "chrome/browser/tab_contents/tab_util.h"
17 #include "chrome/browser/tabs/tab_strip_model.h" 17 #include "chrome/browser/tabs/tab_strip_model.h"
18 #include "chrome/browser/ui/browser_list.h" 18 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/browser/ui/browser_navigator.h" 19 #include "chrome/browser/ui/browser_navigator.h"
20 #include "chrome/browser/ui/intents/web_intent_picker.h" 20 #include "chrome/browser/ui/intents/web_intent_picker.h"
21 #include "chrome/browser/ui/intents/web_intent_picker_model.h" 21 #include "chrome/browser/ui/intents/web_intent_picker_model.h"
22 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 22 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
23 #include "chrome/browser/webdata/web_data_service.h" 23 #include "chrome/browser/webdata/web_data_service.h"
24 #include "chrome/common/chrome_notification_types.h" 24 #include "chrome/common/chrome_notification_types.h"
25 #include "content/browser/intents/intent_injector.h" 25 #include "content/browser/intents/intent_injector.h"
26 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/notification_source.h" 27 #include "content/public/browser/notification_source.h"
27 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_intents_dispatcher.h" 29 #include "content/public/browser/web_intents_dispatcher.h"
30 #include "content/public/common/url_fetcher.h"
31 #include "content/public/common/url_fetcher_delegate.h"
32 #include "net/base/load_flags.h"
33 #include "skia/ext/image_operations.h"
29 #include "ui/gfx/codec/png_codec.h" 34 #include "ui/gfx/codec/png_codec.h"
35 #include "ui/gfx/favicon_size.h"
30 #include "ui/gfx/image/image.h" 36 #include "ui/gfx/image/image.h"
31 #include "webkit/glue/web_intent_service_data.h" 37 #include "webkit/glue/web_intent_service_data.h"
32 38
33 namespace { 39 namespace {
34 40
35 // Gets the favicon service for the profile in |tab_contents|. 41 // Gets the favicon service for the profile in |tab_contents|.
36 FaviconService* GetFaviconService(TabContentsWrapper* wrapper) { 42 FaviconService* GetFaviconService(TabContentsWrapper* wrapper) {
37 return wrapper->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); 43 return wrapper->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS);
38 } 44 }
39 45
(...skipping 13 matching lines...) Expand all
53 case webkit_glue::WebIntentServiceData::DISPOSITION_INLINE: 59 case webkit_glue::WebIntentServiceData::DISPOSITION_INLINE:
54 return WebIntentPickerModel::DISPOSITION_INLINE; 60 return WebIntentPickerModel::DISPOSITION_INLINE;
55 case webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW: 61 case webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW:
56 return WebIntentPickerModel::DISPOSITION_WINDOW; 62 return WebIntentPickerModel::DISPOSITION_WINDOW;
57 default: 63 default:
58 NOTREACHED(); 64 NOTREACHED();
59 return WebIntentPickerModel::DISPOSITION_WINDOW; 65 return WebIntentPickerModel::DISPOSITION_WINDOW;
60 } 66 }
61 } 67 }
62 68
69 class URLFetcherTrampoline : public content::URLFetcherDelegate {
70 public:
71 typedef base::Callback<void(const content::URLFetcher* source)> Callback;
72
73 explicit URLFetcherTrampoline(const Callback& callback)
74 : callback_(callback) {}
75 ~URLFetcherTrampoline() {}
76
77 // content::URLFetcherDelegate implementation.
78 virtual void OnURLFetchComplete(const content::URLFetcher* source) OVERRIDE {
79 callback_.Run(source);
80 delete source;
81 delete this;
82 }
83
84 private:
85 Callback callback_;
86 };
87
63 } // namespace 88 } // namespace
64 89
65 WebIntentPickerController::WebIntentPickerController( 90 WebIntentPickerController::WebIntentPickerController(
66 TabContentsWrapper* wrapper) 91 TabContentsWrapper* wrapper)
67 : wrapper_(wrapper), 92 : wrapper_(wrapper),
68 picker_(NULL), 93 picker_(NULL),
69 picker_model_(new WebIntentPickerModel()), 94 picker_model_(new WebIntentPickerModel()),
70 pending_async_count_(0), 95 pending_async_count_(0),
71 picker_shown_(false), 96 picker_shown_(false),
72 intents_dispatcher_(NULL), 97 intents_dispatcher_(NULL),
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 picker_model_->UpdateFaviconAt(index, icon_image); 303 picker_model_->UpdateFaviconAt(index, icon_image);
279 return; 304 return;
280 } 305 }
281 } 306 }
282 307
283 AsyncOperationFinished(); 308 AsyncOperationFinished();
284 } 309 }
285 310
286 void WebIntentPickerController::OnCWSIntentServicesAvailable( 311 void WebIntentPickerController::OnCWSIntentServicesAvailable(
287 const CWSIntentsRegistry::IntentExtensionList& extensions) { 312 const CWSIntentsRegistry::IntentExtensionList& extensions) {
313 net::URLRequestContextGetter* context =
Greg Billock 2012/02/23 22:15:50 It looks like this can just move down to SetReques
binji 2012/02/23 22:33:41 Done.
314 wrapper_->profile()->GetRequestContext();
315
288 for (size_t i = 0; i < extensions.size(); ++i) { 316 for (size_t i = 0; i < extensions.size(); ++i) {
289 const CWSIntentsRegistry::IntentExtensionInfo& info = extensions[i]; 317 const CWSIntentsRegistry::IntentExtensionInfo& info = extensions[i];
290 picker_model_->AddSuggestedExtension( 318 picker_model_->AddSuggestedExtension(
291 info.name, 319 info.name,
292 info.id, 320 info.id,
293 info.average_rating); 321 info.average_rating);
294 322
295 // TODO(binji): Fetch extension icon. 323 pending_async_count_++;
324 content::URLFetcher* icon_url_fetcher = content::URLFetcher::Create(
325 0,
326 info.icon_url,
327 content::URLFetcher::GET,
328 new URLFetcherTrampoline(
329 base::Bind(
330 &WebIntentPickerController::OnExtensionIconURLFetchComplete,
331 weak_ptr_factory_.GetWeakPtr(), info.id)));
332
333 icon_url_fetcher->SetLoadFlags(
334 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
335 icon_url_fetcher->SetRequestContext(context);
336 icon_url_fetcher->Start();
Greg Billock 2012/02/23 22:15:50 So the URLFetcher always delegates the callback to
binji 2012/02/23 22:33:41 I wasn't 100% on this, so I took a look. It looks
296 } 337 }
297 338
298 AsyncOperationFinished(); 339 AsyncOperationFinished();
299 } 340 }
300 341
342 void WebIntentPickerController::OnExtensionIconURLFetchComplete(
343 const string16& extension_id, const content::URLFetcher* source) {
344 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
345 if (source->GetResponseCode() != 200) {
346 AsyncOperationFinished();
347 return;
348 }
349
350 scoped_ptr<std::string> response(new std::string);
351 if (source->GetResponseAsString(response.get())) {
Greg Billock 2012/02/23 22:15:50 How about if (!...) { AsyncOpFinished; return; }
binji 2012/02/23 22:33:41 Done.
352 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
Greg Billock 2012/02/23 22:15:50 Can take this out (you have it above now).
binji 2012/02/23 22:33:41 Oh, right. :-)
353
354 // Decode PNG and resize on worker thread.
355 content::BrowserThread::PostBlockingPoolTask(
356 FROM_HERE,
357 base::Bind(&DecodeExtensionIconAndResize,
358 base::Passed(&response),
359 base::Bind(
Greg Billock 2012/02/23 22:15:50 I think it'd read easier to extract these two call
binji 2012/02/23 22:33:41 Done.
360 &WebIntentPickerController::OnExtensionIconAvailable,
361 weak_ptr_factory_.GetWeakPtr(),
362 extension_id),
363 base::Bind(
364 &WebIntentPickerController::OnExtensionIconUnavailable,
365 weak_ptr_factory_.GetWeakPtr(),
366 extension_id)));
367 } else {
368 AsyncOperationFinished();
369 }
370 }
371
372 // static
373 void WebIntentPickerController::DecodeExtensionIconAndResize(
374 scoped_ptr<std::string> icon_response,
375 const ExtensionIconAvailableCallback& callback,
376 const base::Closure& unavailable_callback) {
377 SkBitmap icon_bitmap;
378 if (gfx::PNGCodec::Decode(
379 reinterpret_cast<const unsigned char*>(icon_response->data()),
380 icon_response->length(),
381 &icon_bitmap)) {
382 SkBitmap resized_icon = skia::ImageOperations::Resize(
383 icon_bitmap,
384 skia::ImageOperations::RESIZE_BEST,
385 gfx::kFaviconSize, gfx::kFaviconSize);
386 gfx::Image icon_image(new SkBitmap(resized_icon));
387
388 content::BrowserThread::PostTask(
389 content::BrowserThread::UI,
390 FROM_HERE,
391 base::Bind(callback, icon_image));
Greg Billock 2012/02/23 22:15:50 It might be easier to get a WebIntentPickerControl
binji 2012/02/23 22:33:41 This was the original way I wrote it, but it didn'
Greg Billock 2012/02/23 22:51:30 You want to put some of these threading constraint
binji 2012/02/23 23:34:48 Done.
392 } else {
393 content::BrowserThread::PostTask(
394 content::BrowserThread::UI,
395 FROM_HERE,
396 unavailable_callback);
397 }
398 }
399
400 void WebIntentPickerController::OnExtensionIconAvailable(
401 const string16& extension_id,
402 const gfx::Image& icon_image) {
403 picker_model_->SetSuggestedExtensionIconWithId(extension_id, icon_image);
404 AsyncOperationFinished();
405 }
406
407 void WebIntentPickerController::OnExtensionIconUnavailable(
408 const string16& extension_id) {
409 AsyncOperationFinished();
410 }
411
301 void WebIntentPickerController::AsyncOperationFinished() { 412 void WebIntentPickerController::AsyncOperationFinished() {
413 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
302 if (--pending_async_count_ == 0) { 414 if (--pending_async_count_ == 0) {
303 picker_->OnPendingAsyncCompleted(); 415 picker_->OnPendingAsyncCompleted();
304 } 416 }
305 } 417 }
306 418
307 void WebIntentPickerController::ClosePicker() { 419 void WebIntentPickerController::ClosePicker() {
308 if (picker_) { 420 if (picker_) {
309 picker_->Close(); 421 picker_->Close();
310 } 422 }
311 } 423 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698