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

Side by Side Diff: chrome/browser/ui/intents/web_intent_picker_controller.cc

Issue 9595031: [Web Intents] Inline installation of extensions in web intents picker. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 9 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/extensions/webstore_installer.h"
12 #include "chrome/browser/favicon/favicon_service.h" 12 #include "chrome/browser/favicon/favicon_service.h"
13 #include "chrome/browser/intents/default_web_intent_service.h" 13 #include "chrome/browser/intents/default_web_intent_service.h"
14 #include "chrome/browser/intents/web_intents_registry_factory.h" 14 #include "chrome/browser/intents/web_intents_registry_factory.h"
15 #include "chrome/browser/intents/cws_intents_registry_factory.h" 15 #include "chrome/browser/intents/cws_intents_registry_factory.h"
16 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/tab_contents/tab_util.h" 17 #include "chrome/browser/tab_contents/tab_util.h"
18 #include "chrome/browser/tabs/tab_strip_model.h" 18 #include "chrome/browser/tabs/tab_strip_model.h"
19 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_list.h" 20 #include "chrome/browser/ui/browser_list.h"
20 #include "chrome/browser/ui/browser_navigator.h" 21 #include "chrome/browser/ui/browser_navigator.h"
21 #include "chrome/browser/ui/intents/web_intent_picker.h" 22 #include "chrome/browser/ui/intents/web_intent_picker.h"
22 #include "chrome/browser/ui/intents/web_intent_picker_model.h" 23 #include "chrome/browser/ui/intents/web_intent_picker_model.h"
23 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 24 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
24 #include "chrome/browser/webdata/web_data_service.h" 25 #include "chrome/browser/webdata/web_data_service.h"
25 #include "chrome/common/chrome_notification_types.h" 26 #include "chrome/common/chrome_notification_types.h"
26 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/navigation_controller.h"
27 #include "content/public/browser/notification_source.h" 29 #include "content/public/browser/notification_source.h"
28 #include "content/public/browser/web_contents.h" 30 #include "content/public/browser/web_contents.h"
29 #include "content/public/browser/web_intents_dispatcher.h" 31 #include "content/public/browser/web_intents_dispatcher.h"
30 #include "content/public/common/url_fetcher.h" 32 #include "content/public/common/url_fetcher.h"
31 #include "content/public/common/url_fetcher_delegate.h" 33 #include "content/public/common/url_fetcher_delegate.h"
32 #include "net/base/load_flags.h" 34 #include "net/base/load_flags.h"
33 #include "skia/ext/image_operations.h" 35 #include "skia/ext/image_operations.h"
34 #include "ui/gfx/codec/png_codec.h" 36 #include "ui/gfx/codec/png_codec.h"
35 #include "ui/gfx/favicon_size.h" 37 #include "ui/gfx/favicon_size.h"
36 #include "ui/gfx/image/image.h" 38 #include "ui/gfx/image/image.h"
(...skipping 22 matching lines...) Expand all
59 case webkit_glue::WebIntentServiceData::DISPOSITION_INLINE: 61 case webkit_glue::WebIntentServiceData::DISPOSITION_INLINE:
60 return WebIntentPickerModel::DISPOSITION_INLINE; 62 return WebIntentPickerModel::DISPOSITION_INLINE;
61 case webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW: 63 case webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW:
62 return WebIntentPickerModel::DISPOSITION_WINDOW; 64 return WebIntentPickerModel::DISPOSITION_WINDOW;
63 default: 65 default:
64 NOTREACHED(); 66 NOTREACHED();
65 return WebIntentPickerModel::DISPOSITION_WINDOW; 67 return WebIntentPickerModel::DISPOSITION_WINDOW;
66 } 68 }
67 } 69 }
68 70
71 // WebIntentsRegistryTrampoline -----------------------------------------------
James Hawkins 2012/03/15 01:05:20 Kill this line, preferably via fire.
binji 2012/03/15 17:53:14 Done.
72
73 class WebIntentsRegistryTrampoline : public WebIntentsRegistry::Consumer {
James Hawkins 2012/03/15 01:05:20 Document the class.
binji 2012/03/15 17:53:14 Done.
74 public:
75 typedef std::vector<webkit_glue::WebIntentServiceData> IntentServices;
76 typedef base::Callback<void(const IntentServices&)> Callback;
James Hawkins 2012/03/15 01:05:20 Pick a less generic name than Callback.
binji 2012/03/15 17:53:14 Done.
77
78 explicit WebIntentsRegistryTrampoline(const Callback& callback);
James Hawkins 2012/03/15 01:05:20 |callback| must not be null?
binji 2012/03/15 17:53:14 Done.
79 ~WebIntentsRegistryTrampoline();
80
81 // WebIntentsRegistry::Consumer implementation.
82 virtual void OnIntentsQueryDone(
83 WebIntentsRegistry::QueryID,
84 const std::vector<webkit_glue::WebIntentServiceData>& services) OVERRIDE;
85 virtual void OnIntentsDefaultsQueryDone(
86 WebIntentsRegistry::QueryID,
87 const DefaultWebIntentService& default_service) OVERRIDE {}
88
89 private:
90 Callback callback_;
James Hawkins 2012/03/15 01:05:20 Document member variable.
binji 2012/03/15 17:53:14 Done.
91 };
92
93 WebIntentsRegistryTrampoline::WebIntentsRegistryTrampoline(
94 const Callback& callback)
95 : callback_(callback) {
96 }
97
98 WebIntentsRegistryTrampoline::~WebIntentsRegistryTrampoline() {
99 }
100
101 void WebIntentsRegistryTrampoline::OnIntentsQueryDone(
102 WebIntentsRegistry::QueryID,
103 const std::vector<webkit_glue::WebIntentServiceData>& services) {
104 callback_.Run(services);
105 delete this;
106 }
107
108 // URLFetcherTrampoline -------------------------------------------------------
109
69 class URLFetcherTrampoline : public content::URLFetcherDelegate { 110 class URLFetcherTrampoline : public content::URLFetcherDelegate {
70 public: 111 public:
71 typedef base::Callback<void(const content::URLFetcher* source)> Callback; 112 typedef base::Callback<void(const content::URLFetcher* source)> Callback;
72 113
73 explicit URLFetcherTrampoline(const Callback& callback) 114 explicit URLFetcherTrampoline(const Callback& callback);
74 : callback_(callback) {} 115 ~URLFetcherTrampoline();
75 ~URLFetcherTrampoline() {}
76 116
77 // content::URLFetcherDelegate implementation. 117 // content::URLFetcherDelegate implementation.
78 virtual void OnURLFetchComplete(const content::URLFetcher* source) OVERRIDE { 118 virtual void OnURLFetchComplete(const content::URLFetcher* source) OVERRIDE;
79 callback_.Run(source);
80 delete source;
81 delete this;
82 }
83 119
84 private: 120 private:
85 Callback callback_; 121 Callback callback_;
86 }; 122 };
87 123
124 URLFetcherTrampoline::URLFetcherTrampoline(const Callback& callback)
125 : callback_(callback) {
126 }
127
128 URLFetcherTrampoline::~URLFetcherTrampoline() {
129 }
130
131 void URLFetcherTrampoline::OnURLFetchComplete(
132 const content::URLFetcher* source) {
133 callback_.Run(source);
134 delete source;
135 delete this;
136 }
137
88 } // namespace 138 } // namespace
89 139
90 WebIntentPickerController::WebIntentPickerController( 140 WebIntentPickerController::WebIntentPickerController(
91 TabContentsWrapper* wrapper) 141 TabContentsWrapper* wrapper)
92 : wrapper_(wrapper), 142 : wrapper_(wrapper),
93 picker_(NULL), 143 picker_(NULL),
94 picker_model_(new WebIntentPickerModel()), 144 picker_model_(new WebIntentPickerModel()),
95 pending_async_count_(0), 145 pending_async_count_(0),
96 picker_shown_(false), 146 picker_shown_(false),
97 intents_dispatcher_(NULL), 147 intents_dispatcher_(NULL),
(...skipping 19 matching lines...) Expand all
117 } 167 }
118 168
119 void WebIntentPickerController::ShowDialog(Browser* browser, 169 void WebIntentPickerController::ShowDialog(Browser* browser,
120 const string16& action, 170 const string16& action,
121 const string16& type) { 171 const string16& type) {
122 // Only show a picker once. 172 // Only show a picker once.
123 if (picker_shown_) 173 if (picker_shown_)
124 return; 174 return;
125 175
126 picker_model_->Clear(); 176 picker_model_->Clear();
177 picker_model_->set_action(action);
178 picker_model_->set_mimetype(type);
127 179
128 // If picker is non-NULL, it was set by a test. 180 // If picker is non-NULL, it was set by a test.
129 if (picker_ == NULL) { 181 if (picker_ == NULL) {
130 picker_ = WebIntentPicker::Create(browser, wrapper_, this, 182 picker_ = WebIntentPicker::Create(browser, wrapper_, this,
131 picker_model_.get()); 183 picker_model_.get());
132 } 184 }
133 185
134 picker_shown_ = true; 186 picker_shown_ = true;
135 pending_async_count_+= 2; 187 pending_async_count_+= 2;
136 GetWebIntentsRegistry(wrapper_)->GetIntentServices(action, type, this); 188 GetWebIntentsRegistry(wrapper_)->GetIntentServices(
137 GetCWSIntentsRegistry(wrapper_)->GetIntentServices(action, type, 189 action, type,
190 new WebIntentsRegistryTrampoline(
James Hawkins 2012/03/15 01:05:20 Document ownership.
binji 2012/03/15 17:53:14 Done.
191 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable,
192 weak_ptr_factory_.GetWeakPtr())));
193 GetCWSIntentsRegistry(wrapper_)->GetIntentServices(
194 action, type,
138 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, 195 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable,
139 weak_ptr_factory_.GetWeakPtr())); 196 weak_ptr_factory_.GetWeakPtr()));
140 } 197 }
141 198
142 void WebIntentPickerController::Observe( 199 void WebIntentPickerController::Observe(
143 int type, 200 int type,
144 const content::NotificationSource& source, 201 const content::NotificationSource& source,
145 const content::NotificationDetails& details) { 202 const content::NotificationDetails& details) {
146 DCHECK(type == content::NOTIFICATION_LOAD_START || 203 DCHECK(type == content::NOTIFICATION_LOAD_START ||
147 type == content::NOTIFICATION_TAB_CLOSING); 204 type == content::NOTIFICATION_TAB_CLOSING);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 break; 257 break;
201 } 258 }
202 } 259 }
203 260
204 void WebIntentPickerController::OnInlineDispositionWebContentsCreated( 261 void WebIntentPickerController::OnInlineDispositionWebContentsCreated(
205 content::WebContents* web_contents) { 262 content::WebContents* web_contents) {
206 if (web_contents) 263 if (web_contents)
207 intents_dispatcher_->DispatchIntent(web_contents); 264 intents_dispatcher_->DispatchIntent(web_contents);
208 } 265 }
209 266
267 void WebIntentPickerController::OnExtensionInstallRequested(
268 const std::string& id) {
269 webstore_installer_ = new WebstoreInstaller(
270 wrapper_->profile(),
James Hawkins 2012/03/15 01:05:20 Save rows by collapsing these parameters.
binji 2012/03/15 17:53:14 Done.
271 this,
272 &wrapper_->web_contents()->GetController(),
273 id,
274 WebstoreInstaller::FLAG_INLINE_INSTALL);
275
276 pending_async_count_++;
277 webstore_installer_->Start();
278 }
279
210 void WebIntentPickerController::OnCancelled() { 280 void WebIntentPickerController::OnCancelled() {
211 if (!intents_dispatcher_) 281 if (!intents_dispatcher_)
212 return; 282 return;
213 283
214 if (service_tab_) { 284 if (service_tab_) {
215 intents_dispatcher_->SendReplyMessage( 285 intents_dispatcher_->SendReplyMessage(
216 webkit_glue::WEB_INTENT_SERVICE_TAB_CLOSED, string16()); 286 webkit_glue::WEB_INTENT_SERVICE_TAB_CLOSED, string16());
217 } else { 287 } else {
218 intents_dispatcher_->SendReplyMessage( 288 intents_dispatcher_->SendReplyMessage(
219 webkit_glue::WEB_INTENT_PICKER_CANCELLED, string16()); 289 webkit_glue::WEB_INTENT_PICKER_CANCELLED, string16());
220 } 290 }
221 291
222 ClosePicker(); 292 ClosePicker();
223 } 293 }
224 294
225 void WebIntentPickerController::OnClosing() { 295 void WebIntentPickerController::OnClosing() {
226 picker_shown_ = false; 296 picker_shown_ = false;
227 picker_ = NULL; 297 picker_ = NULL;
228 } 298 }
229 299
300 void WebIntentPickerController::OnExtensionInstallSuccess(
301 const std::string& id) {
302 picker_->OnExtensionInstallSuccess(id);
303 pending_async_count_++;
304 GetWebIntentsRegistry(wrapper_)->GetIntentServicesWithExtensionId(
305 picker_model_->action(),
306 picker_model_->mimetype(),
307 id,
308 new WebIntentsRegistryTrampoline(
309 base::Bind(
310 &WebIntentPickerController::OnExtensionInstallServiceAvailable,
311 weak_ptr_factory_.GetWeakPtr())));
312 AsyncOperationFinished();
313 }
314
315 void WebIntentPickerController::OnExtensionInstallFailure(
316 const std::string& id,
317 const std::string& error) {
318 picker_->OnExtensionInstallFailure(id);
319 AsyncOperationFinished();
320 }
321
230 void WebIntentPickerController::OnSendReturnMessage( 322 void WebIntentPickerController::OnSendReturnMessage(
231 webkit_glue::WebIntentReplyType reply_type) { 323 webkit_glue::WebIntentReplyType reply_type) {
232 ClosePicker(); 324 ClosePicker();
233 325
234 if (service_tab_ && 326 if (service_tab_ &&
235 reply_type != webkit_glue::WEB_INTENT_SERVICE_TAB_CLOSED) { 327 reply_type != webkit_glue::WEB_INTENT_SERVICE_TAB_CLOSED) {
236 int index = TabStripModel::kNoTab; 328 int index = TabStripModel::kNoTab;
237 Browser* browser = Browser::GetBrowserForController( 329 Browser* browser = Browser::GetBrowserForController(
238 &service_tab_->GetController(), &index); 330 &service_tab_->GetController(), &index);
239 if (browser) { 331 if (browser) {
240 browser->tabstrip_model()->CloseTabContentsAt( 332 browser->tabstrip_model()->CloseTabContentsAt(
241 index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); 333 index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
242 334
243 // Activate source tab. 335 // Activate source tab.
244 Browser* source_browser = 336 Browser* source_browser =
245 BrowserList::FindBrowserWithWebContents(wrapper_->web_contents()); 337 BrowserList::FindBrowserWithWebContents(wrapper_->web_contents());
246 if (source_browser) { 338 if (source_browser) {
247 int source_index = 339 int source_index =
248 source_browser->tabstrip_model()->GetIndexOfTabContents(wrapper_); 340 source_browser->tabstrip_model()->GetIndexOfTabContents(wrapper_);
249 source_browser->ActivateTabAt(source_index, false); 341 source_browser->ActivateTabAt(source_index, false);
250 } 342 }
251 } 343 }
252 service_tab_ = NULL; 344 service_tab_ = NULL;
253 } 345 }
254 346
255 intents_dispatcher_ = NULL; 347 intents_dispatcher_ = NULL;
256 } 348 }
257 349
258 void WebIntentPickerController::OnIntentsQueryDone( 350 void WebIntentPickerController::OnWebIntentServicesAvailable(
259 WebIntentsRegistry::QueryID,
260 const std::vector<webkit_glue::WebIntentServiceData>& services) { 351 const std::vector<webkit_glue::WebIntentServiceData>& services) {
261 FaviconService* favicon_service = GetFaviconService(wrapper_); 352 FaviconService* favicon_service = GetFaviconService(wrapper_);
262 for (size_t i = 0; i < services.size(); ++i) { 353 for (size_t i = 0; i < services.size(); ++i) {
263 picker_model_->AddInstalledService( 354 picker_model_->AddInstalledService(
264 services[i].title, 355 services[i].title,
265 services[i].service_url, 356 services[i].service_url,
266 ConvertDisposition(services[i].disposition)); 357 ConvertDisposition(services[i].disposition));
267 358
268 pending_async_count_++; 359 pending_async_count_++;
269 FaviconService::Handle handle = favicon_service->GetFaviconForURL( 360 FaviconService::Handle handle = favicon_service->GetFaviconForURL(
270 services[i].service_url, 361 services[i].service_url,
271 history::FAVICON, 362 history::FAVICON,
272 &favicon_consumer_, 363 &favicon_consumer_,
273 base::Bind( 364 base::Bind(
274 &WebIntentPickerController::OnFaviconDataAvailable, 365 &WebIntentPickerController::OnFaviconDataAvailable,
275 weak_ptr_factory_.GetWeakPtr())); 366 weak_ptr_factory_.GetWeakPtr()));
276 favicon_consumer_.SetClientData(favicon_service, handle, i); 367 favicon_consumer_.SetClientData(favicon_service, handle, i);
277 } 368 }
278 369
279 AsyncOperationFinished(); 370 AsyncOperationFinished();
280 } 371 }
281 372
282 void WebIntentPickerController::OnIntentsDefaultsQueryDone(
283 WebIntentsRegistry::QueryID,
284 const DefaultWebIntentService& default_service) {
285 }
286
287 void WebIntentPickerController::OnFaviconDataAvailable( 373 void WebIntentPickerController::OnFaviconDataAvailable(
288 FaviconService::Handle handle, history::FaviconData favicon_data) { 374 FaviconService::Handle handle, history::FaviconData favicon_data) {
289 size_t index = favicon_consumer_.GetClientDataForCurrentRequest(); 375 size_t index = favicon_consumer_.GetClientDataForCurrentRequest();
290 if (favicon_data.is_valid()) { 376 if (favicon_data.is_valid()) {
291 SkBitmap icon_bitmap; 377 SkBitmap icon_bitmap;
292 378
293 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(), 379 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(),
294 favicon_data.image_data->size(), 380 favicon_data.image_data->size(),
295 &icon_bitmap)) { 381 &icon_bitmap)) {
296 gfx::Image icon_image(new SkBitmap(icon_bitmap)); 382 gfx::Image icon_image(new SkBitmap(icon_bitmap));
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 const gfx::Image& icon_image) { 495 const gfx::Image& icon_image) {
410 picker_model_->SetSuggestedExtensionIconWithId(extension_id, icon_image); 496 picker_model_->SetSuggestedExtensionIconWithId(extension_id, icon_image);
411 AsyncOperationFinished(); 497 AsyncOperationFinished();
412 } 498 }
413 499
414 void WebIntentPickerController::OnExtensionIconUnavailable( 500 void WebIntentPickerController::OnExtensionIconUnavailable(
415 const string16& extension_id) { 501 const string16& extension_id) {
416 AsyncOperationFinished(); 502 AsyncOperationFinished();
417 } 503 }
418 504
505 void WebIntentPickerController::OnExtensionInstallServiceAvailable(
506 const std::vector<webkit_glue::WebIntentServiceData>& services) {
James Hawkins 2012/03/15 01:05:20 Document in the header that |services| must be a n
binji 2012/03/15 17:53:14 Done.
507 DCHECK(services.size() > 0);
508
509 // TODO(binji): We're going to need to disambiguate if there are multiple
510 // services. For now, just choose the first.
511 const webkit_glue::WebIntentServiceData& service_data = services[0];
512 OnServiceChosen(
513 service_data.service_url,
514 ConvertDisposition(service_data.disposition));
515 AsyncOperationFinished();
516 }
517
419 void WebIntentPickerController::AsyncOperationFinished() { 518 void WebIntentPickerController::AsyncOperationFinished() {
420 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 519 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
421 if (--pending_async_count_ == 0) { 520 if (--pending_async_count_ == 0) {
422 picker_->OnPendingAsyncCompleted(); 521 picker_->OnPendingAsyncCompleted();
423 } 522 }
424 } 523 }
425 524
426 void WebIntentPickerController::ClosePicker() { 525 void WebIntentPickerController::ClosePicker() {
427 if (picker_) { 526 if (picker_) {
428 picker_->Close(); 527 picker_->Close();
429 } 528 }
430 } 529 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698