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

Side by Side Diff: chrome/browser/custom_handlers/protocol_handler_registry.cc

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

Powered by Google App Engine
This is Rietveld 408576698