| 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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/ref_counted.h" |
| 12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 13 #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_deleg
ate.h" | 14 #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_deleg
ate.h" |
| 14 #include "chrome/browser/net/chrome_url_request_context.h" | 15 #include "chrome/browser/net/chrome_url_request_context.h" |
| 15 #include "chrome/browser/prefs/pref_service.h" | 16 #include "chrome/browser/prefs/pref_service.h" |
| 16 #include "chrome/browser/profiles/profile_io_data.h" | 17 #include "chrome/browser/profiles/profile_io_data.h" |
| 17 #include "chrome/common/chrome_notification_types.h" | 18 #include "chrome/common/chrome_notification_types.h" |
| 18 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
| 19 #include "chrome/common/custom_handlers/protocol_handler.h" | 20 #include "chrome/common/custom_handlers/protocol_handler.h" |
| 20 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
| 21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 22 #include "content/public/browser/child_process_security_policy.h" | 23 #include "content/public/browser/child_process_security_policy.h" |
| 23 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 24 #include "net/base/network_delegate.h" | 25 #include "net/base/network_delegate.h" |
| 26 #include "net/url_request/url_request.h" |
| 27 #include "net/url_request/url_request_job.h" |
| 25 #include "net/url_request/url_request_redirect_job.h" | 28 #include "net/url_request/url_request_redirect_job.h" |
| 26 | 29 |
| 27 using content::BrowserThread; | 30 using content::BrowserThread; |
| 28 using content::ChildProcessSecurityPolicy; | 31 using content::ChildProcessSecurityPolicy; |
| 29 | 32 |
| 30 namespace { | 33 namespace { |
| 31 | 34 |
| 35 const ProtocolHandler& LookupHandler( |
| 36 const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map, |
| 37 const std::string& scheme) { |
| 38 ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p = |
| 39 handler_map.find(scheme); |
| 40 |
| 41 if (p != handler_map.end()) |
| 42 return p->second; |
| 43 |
| 44 return ProtocolHandler::EmptyProtocolHandler(); |
| 45 } |
| 46 |
| 32 // If true default protocol handlers will be removed if the OS level | 47 // If true default protocol handlers will be removed if the OS level |
| 33 // registration for a protocol is no longer Chrome. | 48 // registration for a protocol is no longer Chrome. |
| 34 bool ShouldRemoveHandlersNotInOS() { | 49 bool ShouldRemoveHandlersNotInOS() { |
| 35 #if defined(OS_LINUX) | 50 #if defined(OS_LINUX) |
| 36 // We don't do this on Linux as the OS registration there is not reliable, | 51 // We don't do this on Linux as the OS registration there is not reliable, |
| 37 // and Chrome OS doesn't have any notion of OS registration. | 52 // and Chrome OS doesn't have any notion of OS registration. |
| 38 // TODO(benwells): When Linux support is more reliable remove this | 53 // TODO(benwells): When Linux support is more reliable remove this |
| 39 // difference (http://crbug.com/88255). | 54 // difference (http://crbug.com/88255). |
| 40 return false; | 55 return false; |
| 41 #else | 56 #else |
| 42 return ShellIntegration::CanSetAsDefaultProtocolClient() != | 57 return ShellIntegration::CanSetAsDefaultProtocolClient() != |
| 43 ShellIntegration::SET_DEFAULT_NOT_ALLOWED; | 58 ShellIntegration::SET_DEFAULT_NOT_ALLOWED; |
| 44 #endif | 59 #endif |
| 45 } | 60 } |
| 46 | 61 |
| 47 } // namespace | 62 void InstallDefaultProtocolHandlers(ProtocolHandlerRegistry* registry) { |
| 63 // Only chromeos has default protocol handlers at this point. |
| 64 #if defined(OS_CHROMEOS) |
| 65 registry->AddPredefinedHandler( |
| 66 ProtocolHandler::CreateProtocolHandler( |
| 67 "mailto", |
| 68 GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_MAILTO_HANDLER_URL)), |
| 69 l10n_util::GetStringUTF16(IDS_GOOGLE_MAILTO_HANDLER_NAME))); |
| 70 registry->AddPredefinedHandler( |
| 71 ProtocolHandler::CreateProtocolHandler( |
| 72 "webcal", |
| 73 GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_WEBCAL_HANDLER_URL)), |
| 74 l10n_util::GetStringUTF16(IDS_GOOGLE_WEBCAL_HANDLER_NAME))); |
| 75 #endif |
| 76 } |
| 48 | 77 |
| 49 static const ProtocolHandler& LookupHandler( | 78 } // namespace |
| 50 const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map, | 79 |
| 51 const std::string& scheme) { | 80 // Core ------------------------------------------------------------------------ |
| 52 ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p = | 81 |
| 53 handler_map.find(scheme); | 82 // Core is an IO thread specific object. Access to the class should all |
| 54 if (p != handler_map.end()) { | 83 // be done via the IO thread. The registry living on the UI thread makes |
| 55 return p->second; | 84 // a best effort to update the IO object after local updates are completed. |
| 85 class ProtocolHandlerRegistry::Core |
| 86 : public base::RefCountedThreadSafe<ProtocolHandlerRegistry::Core> { |
| 87 public: |
| 88 |
| 89 // Creates a new instance. If |enabled| is true the registry is considered |
| 90 // enabled on the IO thread. |
| 91 explicit Core(bool enabled); |
| 92 |
| 93 // Returns true if the protocol has a default protocol handler. |
| 94 // Should be called only from the IO thread. |
| 95 bool IsHandledProtocol(const std::string& scheme) const; |
| 96 |
| 97 // Clears the default for the provided protocol. |
| 98 // Should be called only from the IO thread. |
| 99 void ClearDefault(const std::string& scheme); |
| 100 |
| 101 // Makes this ProtocolHandler the default handler for its protocol. |
| 102 // Should be called only from the IO thread. |
| 103 void SetDefault(const ProtocolHandler& handler); |
| 104 |
| 105 // Creates a URL request job for the given request if there is a matching |
| 106 // protocol handler, returns NULL otherwise. |
| 107 net::URLRequestJob* MaybeCreateJob(net::URLRequest* request) const; |
| 108 |
| 109 // Indicate that the registry has been enabled in the IO thread's |
| 110 // copy of the data. |
| 111 void Enable() { enabled_ = true; } |
| 112 |
| 113 // Indicate that the registry has been disabled in the IO thread's copy of |
| 114 // the data. |
| 115 void Disable() { enabled_ = false; } |
| 116 |
| 117 private: |
| 118 friend class base::RefCountedThreadSafe<Core>; |
| 119 virtual ~Core(); |
| 120 |
| 121 // Copy of protocol handlers use only on the IO thread. |
| 122 ProtocolHandlerRegistry::ProtocolHandlerMap default_handlers_; |
| 123 |
| 124 // Is the registry enabled on the IO thread. |
| 125 bool enabled_; |
| 126 |
| 127 DISALLOW_COPY_AND_ASSIGN(Core); |
| 128 }; |
| 129 |
| 130 ProtocolHandlerRegistry::Core::Core(bool) : enabled_(true) {} |
| 131 ProtocolHandlerRegistry::Core::~Core() {} |
| 132 |
| 133 bool ProtocolHandlerRegistry::Core::IsHandledProtocol( |
| 134 const std::string& scheme) const { |
| 135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 136 return enabled_ && !LookupHandler(default_handlers_, scheme).IsEmpty(); |
| 137 } |
| 138 |
| 139 void ProtocolHandlerRegistry::Core::ClearDefault(const std::string& scheme) { |
| 140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 141 default_handlers_.erase(scheme); |
| 142 } |
| 143 |
| 144 void ProtocolHandlerRegistry::Core::SetDefault(const ProtocolHandler& handler) { |
| 145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 146 ClearDefault(handler.protocol()); |
| 147 default_handlers_.insert(std::make_pair(handler.protocol(), handler)); |
| 148 } |
| 149 |
| 150 // Create a new job for the supplied |URLRequest| if a default handler |
| 151 // is registered and the associated handler is able to interpret |
| 152 // the url from |request|. |
| 153 net::URLRequestJob* ProtocolHandlerRegistry::Core::MaybeCreateJob( |
| 154 net::URLRequest* request) const { |
| 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 156 |
| 157 ProtocolHandler handler = LookupHandler(default_handlers_, |
| 158 request->url().scheme()); |
| 159 if (handler.IsEmpty()) |
| 160 return NULL; |
| 161 |
| 162 GURL translated_url(handler.TranslateUrl(request->url())); |
| 163 if (!translated_url.is_valid()) |
| 164 return NULL; |
| 165 |
| 166 return new net::URLRequestRedirectJob(request, translated_url); |
| 167 } |
| 168 |
| 169 // URLInterceptor ------------------------------------------------------------ |
| 170 |
| 171 // Instances of this class are produced for ownership by the IO |
| 172 // thread where it handler URL requests. We should never hold |
| 173 // any pointers on this class, only produce them in response to |
| 174 // requests via |ProtocolHandlerRegistry::CreateURLInterceptor|. |
| 175 class ProtocolHandlerRegistry::URLInterceptor |
| 176 : public net::URLRequestJobFactory::Interceptor { |
| 177 public: |
| 178 explicit URLInterceptor(Core* core); |
| 179 virtual ~URLInterceptor(); |
| 180 |
| 181 virtual net::URLRequestJob* MaybeIntercept( |
| 182 net::URLRequest* request) const OVERRIDE; |
| 183 |
| 184 virtual bool WillHandleProtocol(const std::string& protocol) const OVERRIDE; |
| 185 |
| 186 virtual net::URLRequestJob* MaybeInterceptRedirect( |
| 187 const GURL& url, net::URLRequest* request) const OVERRIDE { |
| 188 return NULL; |
| 56 } | 189 } |
| 57 return ProtocolHandler::EmptyProtocolHandler(); | 190 |
| 191 virtual net::URLRequestJob* MaybeInterceptResponse( |
| 192 net::URLRequest* request) const OVERRIDE { |
| 193 return NULL; |
| 194 } |
| 195 |
| 196 private: |
| 197 scoped_refptr<Core> core_; |
| 198 DISALLOW_COPY_AND_ASSIGN(URLInterceptor); |
| 199 }; |
| 200 |
| 201 ProtocolHandlerRegistry::URLInterceptor::URLInterceptor(Core* core) |
| 202 : core_(core) { |
| 203 DCHECK(core_); |
| 204 } |
| 205 |
| 206 ProtocolHandlerRegistry::URLInterceptor::~URLInterceptor() { |
| 207 } |
| 208 |
| 209 net::URLRequestJob* ProtocolHandlerRegistry::URLInterceptor::MaybeIntercept( |
| 210 net::URLRequest* request) const { |
| 211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 212 |
| 213 return core_->MaybeCreateJob(request); |
| 214 } |
| 215 |
| 216 bool ProtocolHandlerRegistry::URLInterceptor::WillHandleProtocol( |
| 217 const std::string& protocol) const { |
| 218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 219 |
| 220 return core_->IsHandledProtocol(protocol); |
| 58 } | 221 } |
| 59 | 222 |
| 60 // DefaultClientObserver ------------------------------------------------------ | 223 // DefaultClientObserver ------------------------------------------------------ |
| 61 | 224 |
| 62 ProtocolHandlerRegistry::DefaultClientObserver::DefaultClientObserver( | 225 ProtocolHandlerRegistry::DefaultClientObserver::DefaultClientObserver( |
| 63 ProtocolHandlerRegistry* registry) | 226 ProtocolHandlerRegistry* registry) |
| 64 : worker_(NULL), | 227 : worker_(NULL), |
| 65 registry_(registry) { | 228 registry_(registry) { |
| 66 DCHECK(registry_); | 229 DCHECK(registry_); |
| 67 } | 230 } |
| 68 | 231 |
| 69 ProtocolHandlerRegistry::DefaultClientObserver::~DefaultClientObserver() { | 232 ProtocolHandlerRegistry::DefaultClientObserver::~DefaultClientObserver() { |
| 70 if (worker_) | 233 if (worker_) |
| 71 worker_->ObserverDestroyed(); | 234 worker_->ObserverDestroyed(); |
| 72 | 235 |
| 73 DefaultClientObserverList::iterator iter = std::find( | 236 DefaultClientObserverList::iterator iter = std::find( |
| 74 registry_->default_client_observers_.begin(), | 237 registry_->default_client_observers_.begin(), |
| 75 registry_->default_client_observers_.end(), this); | 238 registry_->default_client_observers_.end(), this); |
| 76 registry_->default_client_observers_.erase(iter); | 239 registry_->default_client_observers_.erase(iter); |
| 77 } | 240 } |
| 78 | 241 |
| 79 void | 242 void ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState( |
| 80 ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState( | |
| 81 ShellIntegration::DefaultWebClientUIState state) { | 243 ShellIntegration::DefaultWebClientUIState state) { |
| 82 if (worker_) { | 244 if (worker_) { |
| 83 if (ShouldRemoveHandlersNotInOS() && | 245 if (ShouldRemoveHandlersNotInOS() && |
| 84 (state == ShellIntegration::STATE_NOT_DEFAULT)) { | 246 (state == ShellIntegration::STATE_NOT_DEFAULT)) { |
| 85 registry_->ClearDefault(worker_->protocol()); | 247 registry_->ClearDefault(worker_->protocol()); |
| 86 } | 248 } |
| 87 } else { | 249 } else { |
| 88 NOTREACHED(); | 250 NOTREACHED(); |
| 89 } | 251 } |
| 90 } | 252 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 worker->StartSetAsDefault(); | 306 worker->StartSetAsDefault(); |
| 145 } | 307 } |
| 146 | 308 |
| 147 // ProtocolHandlerRegistry ----------------------------------------------------- | 309 // ProtocolHandlerRegistry ----------------------------------------------------- |
| 148 | 310 |
| 149 ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile, | 311 ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile, |
| 150 Delegate* delegate) | 312 Delegate* delegate) |
| 151 : profile_(profile), | 313 : profile_(profile), |
| 152 delegate_(delegate), | 314 delegate_(delegate), |
| 153 enabled_(true), | 315 enabled_(true), |
| 154 enabled_io_(enabled_), | |
| 155 is_loading_(false), | 316 is_loading_(false), |
| 156 is_loaded_(false) { | 317 is_loaded_(false), |
| 318 core_(new Core(enabled_)){ |
| 157 } | 319 } |
| 158 | 320 |
| 159 bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest( | 321 bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest( |
| 160 const ProtocolHandler& handler) { | 322 const ProtocolHandler& handler) { |
| 161 if (handler.IsEmpty() || !CanSchemeBeOverridden(handler.protocol())) | 323 if (handler.IsEmpty() || !CanSchemeBeOverridden(handler.protocol())) |
| 162 return true; | 324 return true; |
| 163 | 325 |
| 164 if (!enabled() || IsRegistered(handler) || HasIgnoredEquivalent(handler)) | 326 if (!enabled() || IsRegistered(handler) || HasIgnoredEquivalent(handler)) |
| 165 return true; | 327 return true; |
| 166 | 328 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 p != handlers->end(); p++) { | 388 p != handlers->end(); p++) { |
| 227 if (handler.IsSameOrigin(*p)) { | 389 if (handler.IsSameOrigin(*p)) { |
| 228 replaced_handlers.push_back(*p); | 390 replaced_handlers.push_back(*p); |
| 229 } | 391 } |
| 230 } | 392 } |
| 231 return replaced_handlers; | 393 return replaced_handlers; |
| 232 } | 394 } |
| 233 | 395 |
| 234 void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) { | 396 void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) { |
| 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 398 |
| 236 default_handlers_.erase(scheme); | 399 default_handlers_.erase(scheme); |
| 237 BrowserThread::PostTask( | 400 BrowserThread::PostTask( |
| 238 BrowserThread::IO, | 401 BrowserThread::IO, |
| 239 FROM_HERE, | 402 FROM_HERE, |
| 240 base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, scheme)); | 403 base::Bind(&Core::ClearDefault, core_, scheme)); |
| 241 Save(); | 404 Save(); |
| 242 NotifyChanged(); | 405 NotifyChanged(); |
| 243 } | 406 } |
| 244 | 407 |
| 245 bool ProtocolHandlerRegistry::IsDefault( | 408 bool ProtocolHandlerRegistry::IsDefault( |
| 246 const ProtocolHandler& handler) const { | 409 const ProtocolHandler& handler) const { |
| 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 248 return GetHandlerFor(handler.protocol()) == handler; | 411 return GetHandlerFor(handler.protocol()) == handler; |
| 249 } | 412 } |
| 250 | 413 |
| 251 void ProtocolHandlerRegistry::Load() { | 414 void ProtocolHandlerRegistry::InitProtocolSettings() { |
| 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 416 |
| 417 // Default protocol handlers must be installed first. |
| 418 InstallDefaultProtocolHandlers(this); |
| 419 |
| 252 // Any further default additions to the table will get rejected from now on. | 420 // Any further default additions to the table will get rejected from now on. |
| 253 is_loaded_ = true; | 421 is_loaded_ = true; |
| 254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 255 is_loading_ = true; | 422 is_loading_ = true; |
| 423 |
| 256 PrefService* prefs = profile_->GetPrefs(); | 424 PrefService* prefs = profile_->GetPrefs(); |
| 257 if (prefs->HasPrefPath(prefs::kCustomHandlersEnabled)) { | 425 if (prefs->HasPrefPath(prefs::kCustomHandlersEnabled)) { |
| 258 enabled_ = prefs->GetBoolean(prefs::kCustomHandlersEnabled); | 426 if (prefs->GetBoolean(prefs::kCustomHandlersEnabled)) { |
| 259 BrowserThread::PostTask( | 427 Enable(); |
| 260 BrowserThread::IO, | 428 } else { |
| 261 FROM_HERE, | 429 Disable(); |
| 262 base::Bind(enabled_ ? &ProtocolHandlerRegistry::EnableIO : | 430 } |
| 263 &ProtocolHandlerRegistry::DisableIO, this)); | |
| 264 } | 431 } |
| 265 std::vector<const DictionaryValue*> registered_handlers = | 432 std::vector<const DictionaryValue*> registered_handlers = |
| 266 GetHandlersFromPref(prefs::kRegisteredProtocolHandlers); | 433 GetHandlersFromPref(prefs::kRegisteredProtocolHandlers); |
| 267 for (std::vector<const DictionaryValue*>::const_iterator p = | 434 for (std::vector<const DictionaryValue*>::const_iterator p = |
| 268 registered_handlers.begin(); | 435 registered_handlers.begin(); |
| 269 p != registered_handlers.end(); ++p) { | 436 p != registered_handlers.end(); ++p) { |
| 270 ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(*p); | 437 ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(*p); |
| 271 RegisterProtocolHandler(handler); | 438 RegisterProtocolHandler(handler); |
| 272 bool is_default = false; | 439 bool is_default = false; |
| 273 if ((*p)->GetBoolean("default", &is_default) && is_default) { | 440 if ((*p)->GetBoolean("default", &is_default) && is_default) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 if (should_notify) | 588 if (should_notify) |
| 422 NotifyChanged(); | 589 NotifyChanged(); |
| 423 } | 590 } |
| 424 | 591 |
| 425 bool ProtocolHandlerRegistry::IsHandledProtocol( | 592 bool ProtocolHandlerRegistry::IsHandledProtocol( |
| 426 const std::string& scheme) const { | 593 const std::string& scheme) const { |
| 427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 594 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 428 return enabled_ && !GetHandlerFor(scheme).IsEmpty(); | 595 return enabled_ && !GetHandlerFor(scheme).IsEmpty(); |
| 429 } | 596 } |
| 430 | 597 |
| 431 bool ProtocolHandlerRegistry::IsHandledProtocolIO( | |
| 432 const std::string& scheme) const { | |
| 433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 434 return enabled_io_ && !LookupHandler(default_handlers_io_, scheme).IsEmpty(); | |
| 435 } | |
| 436 | |
| 437 void ProtocolHandlerRegistry::RemoveHandler( | 598 void ProtocolHandlerRegistry::RemoveHandler( |
| 438 const ProtocolHandler& handler) { | 599 const ProtocolHandler& handler) { |
| 439 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 600 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 440 ProtocolHandlerList& handlers = protocol_handlers_[handler.protocol()]; | 601 ProtocolHandlerList& handlers = protocol_handlers_[handler.protocol()]; |
| 441 ProtocolHandlerList::iterator p = | 602 ProtocolHandlerList::iterator p = |
| 442 std::find(handlers.begin(), handlers.end(), handler); | 603 std::find(handlers.begin(), handlers.end(), handler); |
| 443 if (p != handlers.end()) { | 604 if (p != handlers.end()) { |
| 444 handlers.erase(p); | 605 handlers.erase(p); |
| 445 } | 606 } |
| 446 ProtocolHandlerMap::iterator q = default_handlers_.find(handler.protocol()); | 607 ProtocolHandlerMap::iterator q = default_handlers_.find(handler.protocol()); |
| 447 if (q != default_handlers_.end() && q->second == handler) { | 608 if (q != default_handlers_.end() && q->second == handler) { |
| 448 // Make the new top handler in the list the default. | 609 // Make the new top handler in the list the default. |
| 449 if (!handlers.empty()) { | 610 if (!handlers.empty()) { |
| 450 // NOTE We pass a copy because SetDefault() modifies handlers. | 611 // NOTE We pass a copy because SetDefault() modifies handlers. |
| 451 SetDefault(ProtocolHandler(handlers[0])); | 612 SetDefault(ProtocolHandler(handlers[0])); |
| 452 } else { | 613 } else { |
| 453 BrowserThread::PostTask( | 614 BrowserThread::PostTask( |
| 454 BrowserThread::IO, FROM_HERE, | 615 BrowserThread::IO, FROM_HERE, |
| 455 base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, | 616 base::Bind(&Core::ClearDefault, core_, q->second.protocol())); |
| 456 q->second.protocol())); | 617 |
| 457 default_handlers_.erase(q); | 618 default_handlers_.erase(q); |
| 458 } | 619 } |
| 459 } | 620 } |
| 460 | 621 |
| 461 if (!IsHandledProtocol(handler.protocol())) { | 622 if (!IsHandledProtocol(handler.protocol())) { |
| 462 delegate_->DeregisterExternalHandler(handler.protocol()); | 623 delegate_->DeregisterExternalHandler(handler.protocol()); |
| 463 } | 624 } |
| 464 Save(); | 625 Save(); |
| 465 NotifyChanged(); | 626 NotifyChanged(); |
| 466 } | 627 } |
| 467 | 628 |
| 468 void ProtocolHandlerRegistry::RemoveDefaultHandler(const std::string& scheme) { | 629 void ProtocolHandlerRegistry::RemoveDefaultHandler(const std::string& scheme) { |
| 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 630 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 470 ProtocolHandler current_default = GetHandlerFor(scheme); | 631 ProtocolHandler current_default = GetHandlerFor(scheme); |
| 471 if (!current_default.IsEmpty()) | 632 if (!current_default.IsEmpty()) |
| 472 RemoveHandler(current_default); | 633 RemoveHandler(current_default); |
| 473 } | 634 } |
| 474 | 635 |
| 475 const ProtocolHandler& ProtocolHandlerRegistry::GetHandlerFor( | 636 const ProtocolHandler& ProtocolHandlerRegistry::GetHandlerFor( |
| 476 const std::string& scheme) const { | 637 const std::string& scheme) const { |
| 477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 478 return LookupHandler(default_handlers_, scheme); | 639 return LookupHandler(default_handlers_, scheme); |
| 479 } | 640 } |
| 480 | 641 |
| 481 net::URLRequestJob* ProtocolHandlerRegistry::MaybeCreateJob( | |
| 482 net::URLRequest* request) const { | |
| 483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 484 ProtocolHandler handler = LookupHandler(default_handlers_io_, | |
| 485 request->url().scheme()); | |
| 486 if (handler.IsEmpty()) { | |
| 487 return NULL; | |
| 488 } | |
| 489 GURL translated_url(handler.TranslateUrl(request->url())); | |
| 490 if (!translated_url.is_valid()) { | |
| 491 return NULL; | |
| 492 } | |
| 493 return new net::URLRequestRedirectJob(request, translated_url); | |
| 494 } | |
| 495 | |
| 496 void ProtocolHandlerRegistry::Enable() { | 642 void ProtocolHandlerRegistry::Enable() { |
| 497 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 643 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 498 if (enabled_) { | 644 if (enabled_) { |
| 499 return; | 645 return; |
| 500 } | 646 } |
| 501 enabled_ = true; | 647 enabled_ = true; |
| 502 BrowserThread::PostTask( | 648 BrowserThread::PostTask( |
| 503 BrowserThread::IO, | 649 BrowserThread::IO, |
| 504 FROM_HERE, | 650 FROM_HERE, |
| 505 base::Bind(&ProtocolHandlerRegistry::EnableIO, this)); | 651 base::Bind(&Core::Enable, core_)); |
| 652 |
| 506 ProtocolHandlerMap::const_iterator p; | 653 ProtocolHandlerMap::const_iterator p; |
| 507 for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { | 654 for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { |
| 508 delegate_->RegisterExternalHandler(p->first); | 655 delegate_->RegisterExternalHandler(p->first); |
| 509 } | 656 } |
| 510 Save(); | 657 Save(); |
| 511 NotifyChanged(); | 658 NotifyChanged(); |
| 512 } | 659 } |
| 513 | 660 |
| 514 void ProtocolHandlerRegistry::Disable() { | 661 void ProtocolHandlerRegistry::Disable() { |
| 515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 662 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 516 if (!enabled_) { | 663 if (!enabled_) { |
| 517 return; | 664 return; |
| 518 } | 665 } |
| 519 enabled_ = false; | 666 enabled_ = false; |
| 520 BrowserThread::PostTask( | 667 BrowserThread::PostTask( |
| 521 BrowserThread::IO, | 668 BrowserThread::IO, |
| 522 FROM_HERE, | 669 FROM_HERE, |
| 523 base::Bind(&ProtocolHandlerRegistry::DisableIO, this)); | 670 base::Bind(&Core::Disable, core_)); |
| 671 |
| 524 ProtocolHandlerMap::const_iterator p; | 672 ProtocolHandlerMap::const_iterator p; |
| 525 for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { | 673 for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { |
| 526 delegate_->DeregisterExternalHandler(p->first); | 674 delegate_->DeregisterExternalHandler(p->first); |
| 527 } | 675 } |
| 528 Save(); | 676 Save(); |
| 529 NotifyChanged(); | 677 NotifyChanged(); |
| 530 } | 678 } |
| 531 | 679 |
| 532 void ProtocolHandlerRegistry::Finalize() { | 680 void ProtocolHandlerRegistry::Shutdown() { |
| 533 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 534 delegate_.reset(NULL); | 682 delegate_.reset(NULL); |
| 535 // We free these now in case there are any outstanding workers running. If | 683 // 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 | 684 // we didn't free them they could respond to workers and try to update the |
| 537 // protocol handler registry after it was deleted. | 685 // protocol handler registry after it was deleted. |
| 538 // Observers remove themselves from this list when they are deleted; so | 686 // Observers remove themselves from this list when they are deleted; so |
| 539 // we delete the last item until none are left in the list. | 687 // we delete the last item until none are left in the list. |
| 540 while (!default_client_observers_.empty()) { | 688 while (!default_client_observers_.empty()) { |
| 541 delete default_client_observers_.back(); | 689 delete default_client_observers_.back(); |
| 542 } | 690 } |
| 543 } | 691 } |
| 544 | 692 |
| 545 // static | 693 // static |
| 546 void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) { | 694 void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) { |
| 547 pref_service->RegisterListPref(prefs::kRegisteredProtocolHandlers, | 695 pref_service->RegisterListPref(prefs::kRegisteredProtocolHandlers, |
| 548 PrefService::UNSYNCABLE_PREF); | 696 PrefService::UNSYNCABLE_PREF); |
| 549 pref_service->RegisterListPref(prefs::kIgnoredProtocolHandlers, | 697 pref_service->RegisterListPref(prefs::kIgnoredProtocolHandlers, |
| 550 PrefService::UNSYNCABLE_PREF); | 698 PrefService::UNSYNCABLE_PREF); |
| 551 pref_service->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true, | 699 pref_service->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true, |
| 552 PrefService::UNSYNCABLE_PREF); | 700 PrefService::UNSYNCABLE_PREF); |
| 553 } | 701 } |
| 554 | 702 |
| 555 ProtocolHandlerRegistry::~ProtocolHandlerRegistry() { | 703 ProtocolHandlerRegistry::~ProtocolHandlerRegistry() { |
| 556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 704 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 557 DCHECK(default_client_observers_.empty()); | 705 DCHECK(default_client_observers_.empty()); |
| 558 } | 706 } |
| 559 | 707 |
| 560 void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) { | 708 void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) { |
| 561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 709 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 562 DCHECK(IsRegistered(handler)); | 710 DCHECK(IsRegistered(handler)); |
| 563 ProtocolHandlerMultiMap::iterator p = | 711 ProtocolHandlerMultiMap::iterator p = |
| 564 protocol_handlers_.find(handler.protocol()); | 712 protocol_handlers_.find(handler.protocol()); |
| 565 ProtocolHandlerList& list = p->second; | 713 ProtocolHandlerList& list = p->second; |
| 566 list.erase(std::find(list.begin(), list.end(), handler)); | 714 list.erase(std::find(list.begin(), list.end(), handler)); |
| 567 list.insert(list.begin(), handler); | 715 list.insert(list.begin(), handler); |
| 568 } | 716 } |
| 569 | 717 |
| 570 void ProtocolHandlerRegistry::ClearDefaultIO(const std::string& scheme) { | |
| 571 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 572 default_handlers_io_.erase(scheme); | |
| 573 } | |
| 574 | |
| 575 void ProtocolHandlerRegistry::SetDefaultIO(const ProtocolHandler& handler) { | |
| 576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 577 ClearDefaultIO(handler.protocol()); | |
| 578 default_handlers_io_.insert(std::make_pair(handler.protocol(), handler)); | |
| 579 } | |
| 580 | |
| 581 void ProtocolHandlerRegistry::Save() { | 718 void ProtocolHandlerRegistry::Save() { |
| 582 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 719 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 583 if (is_loading_) { | 720 if (is_loading_) { |
| 584 return; | 721 return; |
| 585 } | 722 } |
| 586 scoped_ptr<Value> registered_protocol_handlers(EncodeRegisteredHandlers()); | 723 scoped_ptr<Value> registered_protocol_handlers(EncodeRegisteredHandlers()); |
| 587 scoped_ptr<Value> ignored_protocol_handlers(EncodeIgnoredHandlers()); | 724 scoped_ptr<Value> ignored_protocol_handlers(EncodeIgnoredHandlers()); |
| 588 scoped_ptr<Value> enabled(Value::CreateBooleanValue(enabled_)); | 725 scoped_ptr<Value> enabled(Value::CreateBooleanValue(enabled_)); |
| 589 profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers, | 726 profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers, |
| 590 *registered_protocol_handlers); | 727 *registered_protocol_handlers); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 611 // If we're not loading, and we are setting a default for a new protocol, | 748 // If we're not loading, and we are setting a default for a new protocol, |
| 612 // register with the OS. | 749 // register with the OS. |
| 613 if (!is_loading_ && p == default_handlers_.end()) | 750 if (!is_loading_ && p == default_handlers_.end()) |
| 614 delegate_->RegisterWithOSAsDefaultClient(handler.protocol(), this); | 751 delegate_->RegisterWithOSAsDefaultClient(handler.protocol(), this); |
| 615 default_handlers_.erase(handler.protocol()); | 752 default_handlers_.erase(handler.protocol()); |
| 616 default_handlers_.insert(std::make_pair(handler.protocol(), handler)); | 753 default_handlers_.insert(std::make_pair(handler.protocol(), handler)); |
| 617 PromoteHandler(handler); | 754 PromoteHandler(handler); |
| 618 BrowserThread::PostTask( | 755 BrowserThread::PostTask( |
| 619 BrowserThread::IO, | 756 BrowserThread::IO, |
| 620 FROM_HERE, | 757 FROM_HERE, |
| 621 base::Bind(&ProtocolHandlerRegistry::SetDefaultIO, this, handler)); | 758 base::Bind(&Core::SetDefault, core_, handler)); |
| 622 } | 759 } |
| 623 | 760 |
| 624 void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) { | 761 void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) { |
| 625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 626 ProtocolHandlerMultiMap::iterator p = | 763 ProtocolHandlerMultiMap::iterator p = |
| 627 protocol_handlers_.find(handler.protocol()); | 764 protocol_handlers_.find(handler.protocol()); |
| 628 | 765 |
| 629 if (p != protocol_handlers_.end()) { | 766 if (p != protocol_handlers_.end()) { |
| 630 p->second.push_back(handler); | 767 p->second.push_back(handler); |
| 631 return; | 768 return; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 } | 845 } |
| 709 | 846 |
| 710 void ProtocolHandlerRegistry::IgnoreProtocolHandler( | 847 void ProtocolHandlerRegistry::IgnoreProtocolHandler( |
| 711 const ProtocolHandler& handler) { | 848 const ProtocolHandler& handler) { |
| 712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 849 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 713 ignored_protocol_handlers_.push_back(handler); | 850 ignored_protocol_handlers_.push_back(handler); |
| 714 } | 851 } |
| 715 | 852 |
| 716 void ProtocolHandlerRegistry::AddPredefinedHandler( | 853 void ProtocolHandlerRegistry::AddPredefinedHandler( |
| 717 const ProtocolHandler& handler) { | 854 const ProtocolHandler& handler) { |
| 718 // If called after the load command was issued this function will fail. | 855 DCHECK(!is_loaded_); // Must be called prior InitProtocolSettings. |
| 719 DCHECK(!is_loaded_); | |
| 720 RegisterProtocolHandler(handler); | 856 RegisterProtocolHandler(handler); |
| 721 SetDefault(handler); | 857 SetDefault(handler); |
| 722 } | 858 } |
| 723 | 859 |
| 724 | 860 net::URLRequestJobFactory::Interceptor* |
| 861 ProtocolHandlerRegistry::CreateURLInterceptor() { |
| 862 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 863 // this is always created on the UI thread (in profile_io's |
| 864 // InitializeOnUIThread. Any method calls must be done |
| 865 // on the IO thread (this is checked). |
| 866 return new URLInterceptor(core_); |
| 867 } |
| OLD | NEW |