Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 } | 131 } |
| 132 | 132 |
| 133 } // namespace | 133 } // namespace |
| 134 | 134 |
| 135 WebIntentPickerController::WebIntentPickerController( | 135 WebIntentPickerController::WebIntentPickerController( |
| 136 TabContentsWrapper* wrapper) | 136 TabContentsWrapper* wrapper) |
| 137 : wrapper_(wrapper), | 137 : wrapper_(wrapper), |
| 138 picker_(NULL), | 138 picker_(NULL), |
| 139 picker_model_(new WebIntentPickerModel()), | 139 picker_model_(new WebIntentPickerModel()), |
| 140 pending_async_count_(0), | 140 pending_async_count_(0), |
| 141 pending_registry_calls_count_(0), | |
| 141 picker_shown_(false), | 142 picker_shown_(false), |
| 142 intents_dispatcher_(NULL), | 143 intents_dispatcher_(NULL), |
| 143 service_tab_(NULL), | 144 service_tab_(NULL), |
| 144 weak_ptr_factory_(this) { | 145 weak_ptr_factory_(this) { |
| 145 content::NavigationController* controller = | 146 content::NavigationController* controller = |
| 146 &wrapper->web_contents()->GetController(); | 147 &wrapper->web_contents()->GetController(); |
| 147 registrar_.Add(this, content::NOTIFICATION_LOAD_START, | 148 registrar_.Add(this, content::NOTIFICATION_LOAD_START, |
| 148 content::Source<content::NavigationController>(controller)); | 149 content::Source<content::NavigationController>(controller)); |
| 149 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, | 150 registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, |
| 150 content::Source<content::NavigationController>(controller)); | 151 content::Source<content::NavigationController>(controller)); |
| 151 } | 152 } |
| 152 | 153 |
| 153 WebIntentPickerController::~WebIntentPickerController() { | 154 WebIntentPickerController::~WebIntentPickerController() { |
| 154 } | 155 } |
| 155 | 156 |
| 156 // TODO(gbillock): combine this with ShowDialog. | 157 // TODO(gbillock): combine this with ShowDialog. |
| 157 void WebIntentPickerController::SetIntentsDispatcher( | 158 void WebIntentPickerController::SetIntentsDispatcher( |
| 158 content::WebIntentsDispatcher* intents_dispatcher) { | 159 content::WebIntentsDispatcher* intents_dispatcher) { |
| 159 intents_dispatcher_ = intents_dispatcher; | 160 intents_dispatcher_ = intents_dispatcher; |
| 160 intents_dispatcher_->RegisterReplyNotification( | 161 intents_dispatcher_->RegisterReplyNotification( |
| 161 base::Bind(&WebIntentPickerController::OnSendReturnMessage, | 162 base::Bind(&WebIntentPickerController::OnSendReturnMessage, |
| 162 weak_ptr_factory_.GetWeakPtr())); | 163 weak_ptr_factory_.GetWeakPtr())); |
| 163 } | 164 } |
| 164 | 165 |
| 166 // TODO(gbillock): remove the browser arg; unused. | |
| 165 void WebIntentPickerController::ShowDialog(Browser* browser, | 167 void WebIntentPickerController::ShowDialog(Browser* browser, |
| 166 const string16& action, | 168 const string16& action, |
| 167 const string16& type) { | 169 const string16& type) { |
| 168 // Only show a picker once. | 170 // Only show a picker once. |
| 169 // TODO(gbillock): There's a hole potentially admitting multiple | 171 // TODO(gbillock): There's a hole potentially admitting multiple |
| 170 // in-flight dispatches since we don't create the picker | 172 // in-flight dispatches since we don't create the picker |
| 171 // in this method, but only after calling the registry. | 173 // in this method, but only after calling the registry. |
| 172 if (picker_shown_) { | 174 if (picker_shown_) { |
| 173 if (intents_dispatcher_) { | 175 if (intents_dispatcher_) { |
| 174 intents_dispatcher_->SendReplyMessage( | 176 intents_dispatcher_->SendReplyMessage( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 // required to find disposition set by service.) | 213 // required to find disposition set by service.) |
| 212 pending_async_count_++; | 214 pending_async_count_++; |
| 213 GetWebIntentsRegistry(wrapper_)->GetIntentServices( | 215 GetWebIntentsRegistry(wrapper_)->GetIntentServices( |
| 214 action, type, base::Bind( | 216 action, type, base::Bind( |
| 215 &WebIntentPickerController::WebIntentServicesForExplicitIntent, | 217 &WebIntentPickerController::WebIntentServicesForExplicitIntent, |
| 216 weak_ptr_factory_.GetWeakPtr())); | 218 weak_ptr_factory_.GetWeakPtr())); |
| 217 return; | 219 return; |
| 218 } | 220 } |
| 219 } | 221 } |
| 220 | 222 |
| 221 pending_async_count_+= 2; | 223 pending_async_count_ += 2; |
| 224 pending_registry_calls_count_ += 1; | |
| 225 | |
| 222 GetWebIntentsRegistry(wrapper_)->GetIntentServices( | 226 GetWebIntentsRegistry(wrapper_)->GetIntentServices( |
| 223 action, type, | 227 action, type, |
| 224 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable, | 228 base::Bind(&WebIntentPickerController::OnWebIntentServicesAvailable, |
| 225 weak_ptr_factory_.GetWeakPtr())); | 229 weak_ptr_factory_.GetWeakPtr())); |
| 230 | |
| 231 GURL invoking_url = wrapper_->web_contents()->GetURL(); | |
| 232 if (invoking_url.is_valid()) { | |
| 233 pending_async_count_++; | |
| 234 pending_registry_calls_count_++; | |
| 235 GetWebIntentsRegistry(wrapper_)->GetDefaultIntentService( | |
| 236 action, type, invoking_url, | |
| 237 base::Bind(&WebIntentPickerController::OnWebIntentDefaultsAvailable, | |
| 238 weak_ptr_factory_.GetWeakPtr())); | |
| 239 } | |
| 240 | |
| 226 GetCWSIntentsRegistry(wrapper_)->GetIntentServices( | 241 GetCWSIntentsRegistry(wrapper_)->GetIntentServices( |
| 227 action, type, | 242 action, type, |
| 228 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, | 243 base::Bind(&WebIntentPickerController::OnCWSIntentServicesAvailable, |
| 229 weak_ptr_factory_.GetWeakPtr())); | 244 weak_ptr_factory_.GetWeakPtr())); |
| 230 } | 245 } |
| 231 | 246 |
| 232 void WebIntentPickerController::Observe( | 247 void WebIntentPickerController::Observe( |
| 233 int type, | 248 int type, |
| 234 const content::NotificationSource& source, | 249 const content::NotificationSource& source, |
| 235 const content::NotificationDetails& details) { | 250 const content::NotificationDetails& details) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 FaviconService::Handle handle = favicon_service->GetFaviconForURL( | 422 FaviconService::Handle handle = favicon_service->GetFaviconForURL( |
| 408 services[i].service_url, | 423 services[i].service_url, |
| 409 history::FAVICON, | 424 history::FAVICON, |
| 410 &favicon_consumer_, | 425 &favicon_consumer_, |
| 411 base::Bind( | 426 base::Bind( |
| 412 &WebIntentPickerController::OnFaviconDataAvailable, | 427 &WebIntentPickerController::OnFaviconDataAvailable, |
| 413 weak_ptr_factory_.GetWeakPtr())); | 428 weak_ptr_factory_.GetWeakPtr())); |
| 414 favicon_consumer_.SetClientData(favicon_service, handle, i); | 429 favicon_consumer_.SetClientData(favicon_service, handle, i); |
| 415 } | 430 } |
| 416 | 431 |
| 432 RegistryCallsCompleted(); | |
| 417 AsyncOperationFinished(); | 433 AsyncOperationFinished(); |
| 418 | |
| 419 CreatePicker(); | |
| 420 picker_->SetActionString(GetIntentActionString( | |
| 421 UTF16ToUTF8(picker_model_->action()))); | |
| 422 } | 434 } |
| 423 | 435 |
| 424 void WebIntentPickerController::WebIntentServicesForExplicitIntent( | 436 void WebIntentPickerController::WebIntentServicesForExplicitIntent( |
| 425 const std::vector<webkit_glue::WebIntentServiceData>& services) { | 437 const std::vector<webkit_glue::WebIntentServiceData>& services) { |
| 426 DCHECK(intents_dispatcher_); | 438 DCHECK(intents_dispatcher_); |
| 427 DCHECK(intents_dispatcher_->GetIntent().service.is_valid()); | 439 DCHECK(intents_dispatcher_->GetIntent().service.is_valid()); |
| 428 for (size_t i = 0; i < services.size(); ++i) { | 440 for (size_t i = 0; i < services.size(); ++i) { |
| 429 if (services[i].service_url != intents_dispatcher_->GetIntent().service) | 441 if (services[i].service_url != intents_dispatcher_->GetIntent().service) |
| 430 continue; | 442 continue; |
| 431 | 443 |
| 432 if (services[i].disposition == | 444 if (services[i].disposition == |
| 433 webkit_glue::WebIntentServiceData::DISPOSITION_INLINE) | 445 webkit_glue::WebIntentServiceData::DISPOSITION_INLINE) |
| 434 CreatePicker(); | 446 CreatePicker(); |
| 435 OnServiceChosen(services[i].service_url, | 447 OnServiceChosen(services[i].service_url, |
| 436 ConvertDisposition(services[i].disposition)); | 448 ConvertDisposition(services[i].disposition)); |
| 437 AsyncOperationFinished(); | 449 AsyncOperationFinished(); |
| 438 return; | 450 return; |
| 439 } | 451 } |
| 440 | 452 |
| 441 // No acceptable extension. The intent cannot be dispatched. | 453 // No acceptable extension. The intent cannot be dispatched. |
| 442 intents_dispatcher_->SendReplyMessage( | 454 intents_dispatcher_->SendReplyMessage( |
| 443 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16( | 455 webkit_glue::WEB_INTENT_REPLY_FAILURE, ASCIIToUTF16( |
| 444 "Explicit extension URL is not available.")); | 456 "Explicit extension URL is not available.")); |
| 445 | 457 |
| 446 AsyncOperationFinished(); | 458 AsyncOperationFinished(); |
| 447 } | 459 } |
| 448 | 460 |
| 461 void WebIntentPickerController::OnWebIntentDefaultsAvailable( | |
| 462 const DefaultWebIntentService& default_service) { | |
| 463 if (!default_service.service_url.empty()) { | |
| 464 DCHECK(default_service.suppression == 0); | |
| 465 picker_model_->set_default_service_url(default_service.service_url); | |
| 466 } | |
| 467 | |
| 468 RegistryCallsCompleted(); | |
| 469 AsyncOperationFinished(); | |
| 470 } | |
| 471 | |
| 472 void WebIntentPickerController::RegistryCallsCompleted() { | |
| 473 pending_registry_calls_count_--; | |
| 474 if (pending_registry_calls_count_ != 0) return; | |
| 475 | |
| 476 if (!picker_model_->default_service_url().empty()) { | |
| 477 // If there's a default service, dispatch to it immediately | |
| 478 // without showing the picker. | |
| 479 const WebIntentPickerModel::InstalledService* default_service = | |
|
groby-ooo-7-16
2012/05/01 15:28:33
I'm wondering if we should just keep a InstalledSe
Greg Billock
2012/05/01 19:17:54
That makes sense. Let's refactor that separately?
| |
| 480 picker_model_->GetInstalledServiceWithURL( | |
| 481 GURL(picker_model_->default_service_url())); | |
| 482 | |
| 483 if (default_service != NULL) { | |
| 484 if (default_service->disposition == | |
| 485 WebIntentPickerModel::DISPOSITION_INLINE) | |
| 486 CreatePicker(); | |
| 487 | |
| 488 OnServiceChosen(default_service->url, default_service->disposition); | |
| 489 return; | |
| 490 } | |
| 491 } | |
| 492 | |
| 493 CreatePicker(); | |
| 494 picker_->SetActionString(GetIntentActionString( | |
| 495 UTF16ToUTF8(picker_model_->action()))); | |
| 496 | |
| 497 // TODO(gbillock): handle the case of having only one service -- set | |
| 498 // the make-default checkbox to "true" upon display. | |
|
groby-ooo-7-16
2012/05/01 15:28:33
Probably belongs on the model
Greg Billock
2012/05/01 19:17:54
Done.
| |
| 499 } | |
| 500 | |
| 449 void WebIntentPickerController::OnFaviconDataAvailable( | 501 void WebIntentPickerController::OnFaviconDataAvailable( |
| 450 FaviconService::Handle handle, history::FaviconData favicon_data) { | 502 FaviconService::Handle handle, history::FaviconData favicon_data) { |
| 451 size_t index = favicon_consumer_.GetClientDataForCurrentRequest(); | 503 size_t index = favicon_consumer_.GetClientDataForCurrentRequest(); |
| 452 if (favicon_data.is_valid()) { | 504 if (favicon_data.is_valid()) { |
| 453 SkBitmap icon_bitmap; | 505 SkBitmap icon_bitmap; |
| 454 | 506 |
| 455 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(), | 507 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(), |
| 456 favicon_data.image_data->size(), | 508 favicon_data.image_data->size(), |
| 457 &icon_bitmap)) { | 509 &icon_bitmap)) { |
| 458 gfx::Image icon_image(new SkBitmap(icon_bitmap)); | 510 gfx::Image icon_image(new SkBitmap(icon_bitmap)); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 picker_ = WebIntentPicker::Create(browser, wrapper_, this, | 666 picker_ = WebIntentPicker::Create(browser, wrapper_, this, |
| 615 picker_model_.get()); | 667 picker_model_.get()); |
| 616 } | 668 } |
| 617 picker_shown_ = true; | 669 picker_shown_ = true; |
| 618 } | 670 } |
| 619 | 671 |
| 620 void WebIntentPickerController::ClosePicker() { | 672 void WebIntentPickerController::ClosePicker() { |
| 621 if (picker_) | 673 if (picker_) |
| 622 picker_->Close(); | 674 picker_->Close(); |
| 623 } | 675 } |
| OLD | NEW |