| 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/custom_handlers/protocol_handler_registry.h" | 5 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 // and Chrome OS doesn't have any notion of OS registration. | 37 // and Chrome OS doesn't have any notion of OS registration. |
| 38 // TODO(benwells): When Linux support is more reliable remove this | 38 // TODO(benwells): When Linux support is more reliable remove this |
| 39 // difference (http://crbug.com/88255). | 39 // difference (http://crbug.com/88255). |
| 40 return false; | 40 return false; |
| 41 #else | 41 #else |
| 42 return ShellIntegration::CanSetAsDefaultProtocolClient() != | 42 return ShellIntegration::CanSetAsDefaultProtocolClient() != |
| 43 ShellIntegration::SET_DEFAULT_NOT_ALLOWED; | 43 ShellIntegration::SET_DEFAULT_NOT_ALLOWED; |
| 44 #endif | 44 #endif |
| 45 } | 45 } |
| 46 | 46 |
| 47 void InstallDefaultProtocolHandlers(ProtocolHandlerRegistry* registry) { |
| 48 // only chromeos has default protocol handlers at this point. |
| 49 #if defined(OS_CHROMEOS) |
| 50 registry->AddPredefinedHandler( |
| 51 ProtocolHandler::CreateProtocolHandler( |
| 52 "mailto", |
| 53 GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_MAILTO_HANDLER_URL)), |
| 54 l10n_util::GetStringUTF16(IDS_GOOGLE_MAILTO_HANDLER_NAME))); |
| 55 registry->AddPredefinedHandler( |
| 56 ProtocolHandler::CreateProtocolHandler( |
| 57 "webcal", |
| 58 GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_WEBCAL_HANDLER_URL)), |
| 59 l10n_util::GetStringUTF16(IDS_GOOGLE_WEBCAL_HANDLER_NAME))); |
| 60 #endif |
| 61 } |
| 62 |
| 47 } // namespace | 63 } // namespace |
| 48 | 64 |
| 49 static const ProtocolHandler& LookupHandler( | 65 static const ProtocolHandler& LookupHandler( |
| 50 const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map, | 66 const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map, |
| 51 const std::string& scheme) { | 67 const std::string& scheme) { |
| 52 ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p = | 68 ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p = |
| 53 handler_map.find(scheme); | 69 handler_map.find(scheme); |
| 54 if (p != handler_map.end()) { | 70 if (p != handler_map.end()) { |
| 55 return p->second; | 71 return p->second; |
| 56 } | 72 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 // and it will be automatically freed once all its tasks have finished. | 155 // and it will be automatically freed once all its tasks have finished. |
| 140 scoped_refptr<ShellIntegration::DefaultProtocolClientWorker> worker; | 156 scoped_refptr<ShellIntegration::DefaultProtocolClientWorker> worker; |
| 141 worker = CreateShellWorker(observer, protocol); | 157 worker = CreateShellWorker(observer, protocol); |
| 142 observer->SetWorker(worker); | 158 observer->SetWorker(worker); |
| 143 registry->default_client_observers_.push_back(observer); | 159 registry->default_client_observers_.push_back(observer); |
| 144 worker->StartSetAsDefault(); | 160 worker->StartSetAsDefault(); |
| 145 } | 161 } |
| 146 | 162 |
| 147 // ProtocolHandlerRegistry ----------------------------------------------------- | 163 // ProtocolHandlerRegistry ----------------------------------------------------- |
| 148 | 164 |
| 149 ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile, | 165 ProtocolHandlerRegistry::ProtocolHandlerRegistry( |
| 166 Profile* profile, |
| 150 Delegate* delegate) | 167 Delegate* delegate) |
| 151 : profile_(profile), | 168 : profile_(profile), |
| 152 delegate_(delegate), | 169 delegate_(delegate), |
| 153 enabled_(true), | 170 enabled_(true), |
| 154 enabled_io_(enabled_), | 171 enabled_io_(enabled_), |
| 155 is_loading_(false), | 172 is_loading_(false), |
| 156 is_loaded_(false) { | 173 is_loaded_(false) { |
| 157 } | 174 } |
| 158 | 175 |
| 159 bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest( | 176 bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest( |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 p != handlers->end(); p++) { | 243 p != handlers->end(); p++) { |
| 227 if (handler.IsSameOrigin(*p)) { | 244 if (handler.IsSameOrigin(*p)) { |
| 228 replaced_handlers.push_back(*p); | 245 replaced_handlers.push_back(*p); |
| 229 } | 246 } |
| 230 } | 247 } |
| 231 return replaced_handlers; | 248 return replaced_handlers; |
| 232 } | 249 } |
| 233 | 250 |
| 234 void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) { | 251 void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) { |
| 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 253 |
| 236 default_handlers_.erase(scheme); | 254 default_handlers_.erase(scheme); |
| 237 BrowserThread::PostTask( | 255 BrowserThread::PostTask( |
| 238 BrowserThread::IO, | 256 BrowserThread::IO, |
| 239 FROM_HERE, | 257 FROM_HERE, |
| 240 base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, scheme)); | 258 base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, |
| 259 base::Unretained(this), |
| 260 scheme)); |
| 241 Save(); | 261 Save(); |
| 242 NotifyChanged(); | 262 NotifyChanged(); |
| 243 } | 263 } |
| 244 | 264 |
| 245 bool ProtocolHandlerRegistry::IsDefault( | 265 bool ProtocolHandlerRegistry::IsDefault( |
| 246 const ProtocolHandler& handler) const { | 266 const ProtocolHandler& handler) const { |
| 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 248 return GetHandlerFor(handler.protocol()) == handler; | 268 return GetHandlerFor(handler.protocol()) == handler; |
| 249 } | 269 } |
| 250 | 270 |
| 251 void ProtocolHandlerRegistry::Load() { | 271 void ProtocolHandlerRegistry::InitProtocolSettings() { |
| 272 |
| 273 // Install predefined protocol handlers. |
| 274 InstallDefaultProtocolHandlers(this); |
| 275 |
| 252 // Any further default additions to the table will get rejected from now on. | 276 // Any further default additions to the table will get rejected from now on. |
| 253 is_loaded_ = true; | 277 is_loaded_ = true; |
| 254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 255 is_loading_ = true; | 279 is_loading_ = true; |
| 256 PrefService* prefs = profile_->GetPrefs(); | 280 PrefService* prefs = profile_->GetPrefs(); |
| 257 if (prefs->HasPrefPath(prefs::kCustomHandlersEnabled)) { | 281 if (prefs->HasPrefPath(prefs::kCustomHandlersEnabled)) { |
| 258 enabled_ = prefs->GetBoolean(prefs::kCustomHandlersEnabled); | 282 enabled_ = prefs->GetBoolean(prefs::kCustomHandlersEnabled); |
| 259 BrowserThread::PostTask( | 283 BrowserThread::PostTask( |
| 260 BrowserThread::IO, | 284 BrowserThread::IO, |
| 261 FROM_HERE, | 285 FROM_HERE, |
| 262 base::Bind(enabled_ ? &ProtocolHandlerRegistry::EnableIO : | 286 base::Bind(enabled_ ? |
| 263 &ProtocolHandlerRegistry::DisableIO, this)); | 287 &ProtocolHandlerRegistry::EnableIO : |
| 288 &ProtocolHandlerRegistry::DisableIO, |
| 289 base::Unretained(this))); |
| 264 } | 290 } |
| 265 std::vector<const DictionaryValue*> registered_handlers = | 291 std::vector<const DictionaryValue*> registered_handlers = |
| 266 GetHandlersFromPref(prefs::kRegisteredProtocolHandlers); | 292 GetHandlersFromPref(prefs::kRegisteredProtocolHandlers); |
| 267 for (std::vector<const DictionaryValue*>::const_iterator p = | 293 for (std::vector<const DictionaryValue*>::const_iterator p = |
| 268 registered_handlers.begin(); | 294 registered_handlers.begin(); |
| 269 p != registered_handlers.end(); ++p) { | 295 p != registered_handlers.end(); ++p) { |
| 270 ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(*p); | 296 ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(*p); |
| 271 RegisterProtocolHandler(handler); | 297 RegisterProtocolHandler(handler); |
| 272 bool is_default = false; | 298 bool is_default = false; |
| 273 if ((*p)->GetBoolean("default", &is_default) && is_default) { | 299 if ((*p)->GetBoolean("default", &is_default) && is_default) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 } | 471 } |
| 446 ProtocolHandlerMap::iterator q = default_handlers_.find(handler.protocol()); | 472 ProtocolHandlerMap::iterator q = default_handlers_.find(handler.protocol()); |
| 447 if (q != default_handlers_.end() && q->second == handler) { | 473 if (q != default_handlers_.end() && q->second == handler) { |
| 448 // Make the new top handler in the list the default. | 474 // Make the new top handler in the list the default. |
| 449 if (!handlers.empty()) { | 475 if (!handlers.empty()) { |
| 450 // NOTE We pass a copy because SetDefault() modifies handlers. | 476 // NOTE We pass a copy because SetDefault() modifies handlers. |
| 451 SetDefault(ProtocolHandler(handlers[0])); | 477 SetDefault(ProtocolHandler(handlers[0])); |
| 452 } else { | 478 } else { |
| 453 BrowserThread::PostTask( | 479 BrowserThread::PostTask( |
| 454 BrowserThread::IO, FROM_HERE, | 480 BrowserThread::IO, FROM_HERE, |
| 455 base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, | 481 base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, |
| 482 base::Unretained(this), |
| 456 q->second.protocol())); | 483 q->second.protocol())); |
| 457 default_handlers_.erase(q); | 484 default_handlers_.erase(q); |
| 458 } | 485 } |
| 459 } | 486 } |
| 460 | 487 |
| 461 if (!IsHandledProtocol(handler.protocol())) { | 488 if (!IsHandledProtocol(handler.protocol())) { |
| 462 delegate_->DeregisterExternalHandler(handler.protocol()); | 489 delegate_->DeregisterExternalHandler(handler.protocol()); |
| 463 } | 490 } |
| 464 Save(); | 491 Save(); |
| 465 NotifyChanged(); | 492 NotifyChanged(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 495 | 522 |
| 496 void ProtocolHandlerRegistry::Enable() { | 523 void ProtocolHandlerRegistry::Enable() { |
| 497 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 498 if (enabled_) { | 525 if (enabled_) { |
| 499 return; | 526 return; |
| 500 } | 527 } |
| 501 enabled_ = true; | 528 enabled_ = true; |
| 502 BrowserThread::PostTask( | 529 BrowserThread::PostTask( |
| 503 BrowserThread::IO, | 530 BrowserThread::IO, |
| 504 FROM_HERE, | 531 FROM_HERE, |
| 505 base::Bind(&ProtocolHandlerRegistry::EnableIO, this)); | 532 base::Bind(&ProtocolHandlerRegistry::EnableIO, base::Unretained(this))); |
| 506 ProtocolHandlerMap::const_iterator p; | 533 ProtocolHandlerMap::const_iterator p; |
| 507 for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { | 534 for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { |
| 508 delegate_->RegisterExternalHandler(p->first); | 535 delegate_->RegisterExternalHandler(p->first); |
| 509 } | 536 } |
| 510 Save(); | 537 Save(); |
| 511 NotifyChanged(); | 538 NotifyChanged(); |
| 512 } | 539 } |
| 513 | 540 |
| 514 void ProtocolHandlerRegistry::Disable() { | 541 void ProtocolHandlerRegistry::Disable() { |
| 515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 516 if (!enabled_) { | 543 if (!enabled_) { |
| 517 return; | 544 return; |
| 518 } | 545 } |
| 519 enabled_ = false; | 546 enabled_ = false; |
| 520 BrowserThread::PostTask( | 547 BrowserThread::PostTask( |
| 521 BrowserThread::IO, | 548 BrowserThread::IO, |
| 522 FROM_HERE, | 549 FROM_HERE, |
| 523 base::Bind(&ProtocolHandlerRegistry::DisableIO, this)); | 550 base::Bind(&ProtocolHandlerRegistry::DisableIO, |
| 551 base::Unretained(this))); |
| 524 ProtocolHandlerMap::const_iterator p; | 552 ProtocolHandlerMap::const_iterator p; |
| 525 for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { | 553 for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { |
| 526 delegate_->DeregisterExternalHandler(p->first); | 554 delegate_->DeregisterExternalHandler(p->first); |
| 527 } | 555 } |
| 528 Save(); | 556 Save(); |
| 529 NotifyChanged(); | 557 NotifyChanged(); |
| 530 } | 558 } |
| 531 | 559 |
| 532 void ProtocolHandlerRegistry::Finalize() { | 560 void ProtocolHandlerRegistry::Shutdown() { |
| 533 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 534 delegate_.reset(NULL); | 562 delegate_.reset(NULL); |
| 535 // We free these now in case there are any outstanding workers running. If | 563 // We free these now in case there are any outstanding workers running. If |
| 536 // we didn't free them they could respond to workers and try to update the | 564 // we didn't free them they could respond to workers and try to update the |
| 537 // protocol handler registry after it was deleted. | 565 // protocol handler registry after it was deleted. |
| 538 // Observers remove themselves from this list when they are deleted; so | 566 // Observers remove themselves from this list when they are deleted; so |
| 539 // we delete the last item until none are left in the list. | 567 // we delete the last item until none are left in the list. |
| 540 while (!default_client_observers_.empty()) { | 568 while (!default_client_observers_.empty()) { |
| 541 delete default_client_observers_.back(); | 569 delete default_client_observers_.back(); |
| 542 } | 570 } |
| 543 } | 571 } |
| 544 | 572 |
| 545 // static | 573 // static |
| 546 void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) { | 574 void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) { |
| 547 pref_service->RegisterListPref(prefs::kRegisteredProtocolHandlers, | 575 pref_service->RegisterListPref(prefs::kRegisteredProtocolHandlers, |
| 548 PrefService::UNSYNCABLE_PREF); | 576 PrefService::UNSYNCABLE_PREF); |
| 549 pref_service->RegisterListPref(prefs::kIgnoredProtocolHandlers, | 577 pref_service->RegisterListPref(prefs::kIgnoredProtocolHandlers, |
| 550 PrefService::UNSYNCABLE_PREF); | 578 PrefService::UNSYNCABLE_PREF); |
| 551 pref_service->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true, | 579 pref_service->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true, |
| 552 PrefService::UNSYNCABLE_PREF); | 580 PrefService::UNSYNCABLE_PREF); |
| 553 } | 581 } |
| 554 | 582 |
| 555 ProtocolHandlerRegistry::~ProtocolHandlerRegistry() { | 583 ProtocolHandlerRegistry::~ProtocolHandlerRegistry() { |
| 556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 584 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 557 DCHECK(default_client_observers_.empty()); | 585 DCHECK(default_client_observers_.empty()); |
| 558 } | 586 } |
| 559 | 587 |
| 560 void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) { | 588 void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) { |
| 561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 589 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 562 DCHECK(IsRegistered(handler)); | 590 DCHECK(IsRegistered(handler)); |
| 563 ProtocolHandlerMultiMap::iterator p = | 591 ProtocolHandlerMultiMap::iterator p = |
| 564 protocol_handlers_.find(handler.protocol()); | 592 protocol_handlers_.find(handler.protocol()); |
| 565 ProtocolHandlerList& list = p->second; | 593 ProtocolHandlerList& list = p->second; |
| 566 list.erase(std::find(list.begin(), list.end(), handler)); | 594 list.erase(std::find(list.begin(), list.end(), handler)); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 // If we're not loading, and we are setting a default for a new protocol, | 639 // If we're not loading, and we are setting a default for a new protocol, |
| 612 // register with the OS. | 640 // register with the OS. |
| 613 if (!is_loading_ && p == default_handlers_.end()) | 641 if (!is_loading_ && p == default_handlers_.end()) |
| 614 delegate_->RegisterWithOSAsDefaultClient(handler.protocol(), this); | 642 delegate_->RegisterWithOSAsDefaultClient(handler.protocol(), this); |
| 615 default_handlers_.erase(handler.protocol()); | 643 default_handlers_.erase(handler.protocol()); |
| 616 default_handlers_.insert(std::make_pair(handler.protocol(), handler)); | 644 default_handlers_.insert(std::make_pair(handler.protocol(), handler)); |
| 617 PromoteHandler(handler); | 645 PromoteHandler(handler); |
| 618 BrowserThread::PostTask( | 646 BrowserThread::PostTask( |
| 619 BrowserThread::IO, | 647 BrowserThread::IO, |
| 620 FROM_HERE, | 648 FROM_HERE, |
| 621 base::Bind(&ProtocolHandlerRegistry::SetDefaultIO, this, handler)); | 649 base::Bind(&ProtocolHandlerRegistry::SetDefaultIO, |
| 650 base::Unretained(this), |
| 651 handler)); |
| 622 } | 652 } |
| 623 | 653 |
| 624 void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) { | 654 void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) { |
| 625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 626 ProtocolHandlerMultiMap::iterator p = | 656 ProtocolHandlerMultiMap::iterator p = |
| 627 protocol_handlers_.find(handler.protocol()); | 657 protocol_handlers_.find(handler.protocol()); |
| 628 | 658 |
| 629 if (p != protocol_handlers_.end()) { | 659 if (p != protocol_handlers_.end()) { |
| 630 p->second.push_back(handler); | 660 p->second.push_back(handler); |
| 631 return; | 661 return; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 ignored_protocol_handlers_.push_back(handler); | 743 ignored_protocol_handlers_.push_back(handler); |
| 714 } | 744 } |
| 715 | 745 |
| 716 void ProtocolHandlerRegistry::AddPredefinedHandler( | 746 void ProtocolHandlerRegistry::AddPredefinedHandler( |
| 717 const ProtocolHandler& handler) { | 747 const ProtocolHandler& handler) { |
| 718 // If called after the load command was issued this function will fail. | 748 // If called after the load command was issued this function will fail. |
| 719 DCHECK(!is_loaded_); | 749 DCHECK(!is_loaded_); |
| 720 RegisterProtocolHandler(handler); | 750 RegisterProtocolHandler(handler); |
| 721 SetDefault(handler); | 751 SetDefault(handler); |
| 722 } | 752 } |
| 723 | |
| 724 | |
| OLD | NEW |