diff options
author | smckay@chromium.org <smckay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-21 00:26:32 +0000 |
---|---|---|
committer | smckay@chromium.org <smckay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-21 00:26:32 +0000 |
commit | ab563ff06585024ba472e35a2944ed787202101c (patch) | |
tree | c2699a2f1a6224d93f14e19283db7a958d2d4ed9 | |
parent | 1f4bb9e8d93accfc080f62b419ca312d1f48f11e (diff) | |
download | chromium_src-ab563ff06585024ba472e35a2944ed787202101c.zip chromium_src-ab563ff06585024ba472e35a2944ed787202101c.tar.gz chromium_src-ab563ff06585024ba472e35a2944ed787202101c.tar.bz2 |
Convert ProtocolHandlerRegistry to be a ProfileKeyedService.
BUG=129200
TEST=protocol_handler_registry_browsertest.cc,protocol_handler_registry_unittest.cc
willchan@ -> profile_io changes
+bauerb -> content_settings changes
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=147597
Review URL: https://chromiumcodereview.appspot.com/10546083
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147745 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 586 insertions, 361 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc index 6b994bc..7cadede 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -322,6 +322,10 @@ void MessageLoop::QuitNow() { } } +bool MessageLoop::IsType(Type type) const { + return type_ == type; +} + static void QuitCurrentWhenIdle() { MessageLoop::current()->QuitWhenIdle(); } diff --git a/base/message_loop.h b/base/message_loop.h index eeba6bb..0812c0f 100644 --- a/base/message_loop.h +++ b/base/message_loop.h @@ -258,6 +258,10 @@ class BASE_EXPORT MessageLoop : public base::MessagePump::Delegate { // arbitrary MessageLoop to QuitWhenIdle. static base::Closure QuitWhenIdleClosure(); + // Returns true if this loop is |type|. This allows subclasses (especially + // those in tests) to specialize how they are identified. + virtual bool IsType(Type type) const; + // Returns the type passed to the constructor. Type type() const { return type_; } diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc index 8ac9c64..01fb1b3 100644 --- a/base/message_loop_unittest.cc +++ b/base/message_loop_unittest.cc @@ -2054,3 +2054,10 @@ TEST(MessageLoopTest, ThreadMainTaskRunner) { EXPECT_EQ(foo->test_count(), 1); EXPECT_EQ(foo->result(), "a"); } + +TEST(MessageLoopTest, IsType) { + MessageLoop loop(MessageLoop::TYPE_UI); + EXPECT_TRUE(loop.IsType(MessageLoop::TYPE_UI)); + EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_IO)); + EXPECT_FALSE(loop.IsType(MessageLoop::TYPE_DEFAULT)); +} diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc index 5a6dfae..e9e0c08 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry.cc +++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/logging.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h" #include "chrome/browser/net/chrome_url_request_context.h" @@ -21,14 +22,30 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/notification_service.h" +#include "grit/generated_resources.h" #include "net/base/network_delegate.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_job.h" #include "net/url_request/url_request_redirect_job.h" +#include "ui/base/l10n/l10n_util.h" using content::BrowserThread; using content::ChildProcessSecurityPolicy; namespace { +const ProtocolHandler& LookupHandler( + const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map, + const std::string& scheme) { + ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p = + handler_map.find(scheme); + + if (p != handler_map.end()) + return p->second; + + return ProtocolHandler::EmptyProtocolHandler(); +} + // If true default protocol handlers will be removed if the OS level // registration for a protocol is no longer Chrome. bool ShouldRemoveHandlersNotInOS() { @@ -44,17 +61,149 @@ bool ShouldRemoveHandlersNotInOS() { #endif } -} // namespace +} // namespace -static const ProtocolHandler& LookupHandler( - const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map, - const std::string& scheme) { - ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p = - handler_map.find(scheme); - if (p != handler_map.end()) { - return p->second; +// Core ------------------------------------------------------------------------ + +// Core is an IO thread specific object. Access to the class should all +// be done via the IO thread. The registry living on the UI thread makes +// a best effort to update the IO object after local updates are completed. +class ProtocolHandlerRegistry::Core + : public base::RefCountedThreadSafe<ProtocolHandlerRegistry::Core> { + public: + + // Creates a new instance. If |enabled| is true the registry is considered + // enabled on the IO thread. + explicit Core(bool enabled); + + // Returns true if the protocol has a default protocol handler. + // Should be called only from the IO thread. + bool IsHandledProtocol(const std::string& scheme) const; + + // Clears the default for the provided protocol. + // Should be called only from the IO thread. + void ClearDefault(const std::string& scheme); + + // Makes this ProtocolHandler the default handler for its protocol. + // Should be called only from the IO thread. + void SetDefault(const ProtocolHandler& handler); + + // Creates a URL request job for the given request if there is a matching + // protocol handler, returns NULL otherwise. + net::URLRequestJob* MaybeCreateJob(net::URLRequest* request) const; + + // Indicate that the registry has been enabled in the IO thread's + // copy of the data. + void Enable() { enabled_ = true; } + + // Indicate that the registry has been disabled in the IO thread's copy of + // the data. + void Disable() { enabled_ = false; } + + private: + friend class base::RefCountedThreadSafe<Core>; + virtual ~Core(); + + // Copy of protocol handlers use only on the IO thread. + ProtocolHandlerRegistry::ProtocolHandlerMap default_handlers_; + + // Is the registry enabled on the IO thread. + bool enabled_; + + DISALLOW_COPY_AND_ASSIGN(Core); +}; + +ProtocolHandlerRegistry::Core::Core(bool) : enabled_(true) {} +ProtocolHandlerRegistry::Core::~Core() {} + +bool ProtocolHandlerRegistry::Core::IsHandledProtocol( + const std::string& scheme) const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return enabled_ && !LookupHandler(default_handlers_, scheme).IsEmpty(); +} + +void ProtocolHandlerRegistry::Core::ClearDefault(const std::string& scheme) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + default_handlers_.erase(scheme); +} + +void ProtocolHandlerRegistry::Core::SetDefault(const ProtocolHandler& handler) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + ClearDefault(handler.protocol()); + default_handlers_.insert(std::make_pair(handler.protocol(), handler)); +} + +// Create a new job for the supplied |URLRequest| if a default handler +// is registered and the associated handler is able to interpret +// the url from |request|. +net::URLRequestJob* ProtocolHandlerRegistry::Core::MaybeCreateJob( + net::URLRequest* request) const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + ProtocolHandler handler = LookupHandler(default_handlers_, + request->url().scheme()); + if (handler.IsEmpty()) + return NULL; + + GURL translated_url(handler.TranslateUrl(request->url())); + if (!translated_url.is_valid()) + return NULL; + + return new net::URLRequestRedirectJob(request, translated_url); +} + +// URLInterceptor ------------------------------------------------------------ + +// Instances of this class are produced for ownership by the IO +// thread where it handler URL requests. We should never hold +// any pointers on this class, only produce them in response to +// requests via |ProtocolHandlerRegistry::CreateURLInterceptor|. +class ProtocolHandlerRegistry::URLInterceptor + : public net::URLRequestJobFactory::Interceptor { + public: + explicit URLInterceptor(Core* core); + virtual ~URLInterceptor(); + + virtual net::URLRequestJob* MaybeIntercept( + net::URLRequest* request) const OVERRIDE; + + virtual bool WillHandleProtocol(const std::string& protocol) const OVERRIDE; + + virtual net::URLRequestJob* MaybeInterceptRedirect( + const GURL& url, net::URLRequest* request) const OVERRIDE { + return NULL; } - return ProtocolHandler::EmptyProtocolHandler(); + + virtual net::URLRequestJob* MaybeInterceptResponse( + net::URLRequest* request) const OVERRIDE { + return NULL; + } + + private: + scoped_refptr<Core> core_; + DISALLOW_COPY_AND_ASSIGN(URLInterceptor); +}; + +ProtocolHandlerRegistry::URLInterceptor::URLInterceptor(Core* core) + : core_(core) { + DCHECK(core_); +} + +ProtocolHandlerRegistry::URLInterceptor::~URLInterceptor() { +} + +net::URLRequestJob* ProtocolHandlerRegistry::URLInterceptor::MaybeIntercept( + net::URLRequest* request) const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + return core_->MaybeCreateJob(request); +} + +bool ProtocolHandlerRegistry::URLInterceptor::WillHandleProtocol( + const std::string& protocol) const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + return core_->IsHandledProtocol(protocol); } // DefaultClientObserver ------------------------------------------------------ @@ -76,8 +225,7 @@ ProtocolHandlerRegistry::DefaultClientObserver::~DefaultClientObserver() { registry_->default_client_observers_.erase(iter); } -void -ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState( +void ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState( ShellIntegration::DefaultWebClientUIState state) { if (worker_) { if (ShouldRemoveHandlersNotInOS() && @@ -151,9 +299,9 @@ ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile, : profile_(profile), delegate_(delegate), enabled_(true), - enabled_io_(enabled_), is_loading_(false), - is_loaded_(false) { + is_loaded_(false), + core_(new Core(enabled_)){ } bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest( @@ -233,11 +381,12 @@ ProtocolHandlerRegistry::GetReplacedHandlers( void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + default_handlers_.erase(scheme); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, scheme)); + base::Bind(&Core::ClearDefault, core_, scheme)); Save(); NotifyChanged(); } @@ -248,19 +397,38 @@ bool ProtocolHandlerRegistry::IsDefault( return GetHandlerFor(handler.protocol()) == handler; } -void ProtocolHandlerRegistry::Load() { +void ProtocolHandlerRegistry::InstallDefaultsForChromeOS() { +#if defined(OS_CHROMEOS) + // Only chromeos has default protocol handlers at this point. + AddPredefinedHandler( + ProtocolHandler::CreateProtocolHandler( + "mailto", + GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_MAILTO_HANDLER_URL)), + l10n_util::GetStringUTF16(IDS_GOOGLE_MAILTO_HANDLER_NAME))); + AddPredefinedHandler( + ProtocolHandler::CreateProtocolHandler( + "webcal", + GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_WEBCAL_HANDLER_URL)), + l10n_util::GetStringUTF16(IDS_GOOGLE_WEBCAL_HANDLER_NAME))); +#else + NOTREACHED(); // this method should only ever be called in chromeos. +#endif +} + +void ProtocolHandlerRegistry::InitProtocolSettings() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // Any further default additions to the table will get rejected from now on. is_loaded_ = true; - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); is_loading_ = true; + PrefService* prefs = profile_->GetPrefs(); if (prefs->HasPrefPath(prefs::kCustomHandlersEnabled)) { - enabled_ = prefs->GetBoolean(prefs::kCustomHandlersEnabled); - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(enabled_ ? &ProtocolHandlerRegistry::EnableIO : - &ProtocolHandlerRegistry::DisableIO, this)); + if (prefs->GetBoolean(prefs::kCustomHandlersEnabled)) { + Enable(); + } else { + Disable(); + } } std::vector<const DictionaryValue*> registered_handlers = GetHandlersFromPref(prefs::kRegisteredProtocolHandlers); @@ -428,12 +596,6 @@ bool ProtocolHandlerRegistry::IsHandledProtocol( return enabled_ && !GetHandlerFor(scheme).IsEmpty(); } -bool ProtocolHandlerRegistry::IsHandledProtocolIO( - const std::string& scheme) const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - return enabled_io_ && !LookupHandler(default_handlers_io_, scheme).IsEmpty(); -} - void ProtocolHandlerRegistry::RemoveHandler( const ProtocolHandler& handler) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -452,8 +614,8 @@ void ProtocolHandlerRegistry::RemoveHandler( } else { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, - q->second.protocol())); + base::Bind(&Core::ClearDefault, core_, q->second.protocol())); + default_handlers_.erase(q); } } @@ -478,21 +640,6 @@ const ProtocolHandler& ProtocolHandlerRegistry::GetHandlerFor( return LookupHandler(default_handlers_, scheme); } -net::URLRequestJob* ProtocolHandlerRegistry::MaybeCreateJob( - net::URLRequest* request) const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - ProtocolHandler handler = LookupHandler(default_handlers_io_, - request->url().scheme()); - if (handler.IsEmpty()) { - return NULL; - } - GURL translated_url(handler.TranslateUrl(request->url())); - if (!translated_url.is_valid()) { - return NULL; - } - return new net::URLRequestRedirectJob(request, translated_url); -} - void ProtocolHandlerRegistry::Enable() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (enabled_) { @@ -502,7 +649,8 @@ void ProtocolHandlerRegistry::Enable() { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ProtocolHandlerRegistry::EnableIO, this)); + base::Bind(&Core::Enable, core_)); + ProtocolHandlerMap::const_iterator p; for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { delegate_->RegisterExternalHandler(p->first); @@ -520,7 +668,8 @@ void ProtocolHandlerRegistry::Disable() { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ProtocolHandlerRegistry::DisableIO, this)); + base::Bind(&Core::Disable, core_)); + ProtocolHandlerMap::const_iterator p; for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { delegate_->DeregisterExternalHandler(p->first); @@ -529,7 +678,7 @@ void ProtocolHandlerRegistry::Disable() { NotifyChanged(); } -void ProtocolHandlerRegistry::Finalize() { +void ProtocolHandlerRegistry::Shutdown() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); delegate_.reset(NULL); // We free these now in case there are any outstanding workers running. If @@ -553,7 +702,7 @@ void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) { } ProtocolHandlerRegistry::~ProtocolHandlerRegistry() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(default_client_observers_.empty()); } @@ -567,17 +716,6 @@ void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) { list.insert(list.begin(), handler); } -void ProtocolHandlerRegistry::ClearDefaultIO(const std::string& scheme) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - default_handlers_io_.erase(scheme); -} - -void ProtocolHandlerRegistry::SetDefaultIO(const ProtocolHandler& handler) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - ClearDefaultIO(handler.protocol()); - default_handlers_io_.insert(std::make_pair(handler.protocol(), handler)); -} - void ProtocolHandlerRegistry::Save() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (is_loading_) { @@ -618,7 +756,7 @@ void ProtocolHandlerRegistry::SetDefault(const ProtocolHandler& handler) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ProtocolHandlerRegistry::SetDefaultIO, this, handler)); + base::Bind(&Core::SetDefault, core_, handler)); } void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) { @@ -715,10 +853,16 @@ void ProtocolHandlerRegistry::IgnoreProtocolHandler( void ProtocolHandlerRegistry::AddPredefinedHandler( const ProtocolHandler& handler) { - // If called after the load command was issued this function will fail. - DCHECK(!is_loaded_); + DCHECK(!is_loaded_); // Must be called prior InitProtocolSettings. RegisterProtocolHandler(handler); SetDefault(handler); } - +net::URLRequestJobFactory::Interceptor* + ProtocolHandlerRegistry::CreateURLInterceptor() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // this is always created on the UI thread (in profile_io's + // InitializeOnUIThread. Any method calls must be done + // on the IO thread (this is checked). + return new URLInterceptor(core_); +} diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.h b/chrome/browser/custom_handlers/protocol_handler_registry.h index a74a765..a418ad1 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry.h +++ b/chrome/browser/custom_handlers/protocol_handler_registry.h @@ -20,17 +20,18 @@ #include "content/public/browser/notification_service.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_job.h" +#include "net/url_request/url_request_job_factory.h" // This is where handlers for protocols registered with // navigator.registerProtocolHandler() are registered. Each Profile owns an // instance of this class, which is initialized on browser start through // Profile::InitRegisteredProtocolHandlers(), and they should be the only // instances of this class. +class ProtocolHandlerRegistry : public ProfileKeyedService { -class ProtocolHandlerRegistry - : public base::RefCountedThreadSafe< - ProtocolHandlerRegistry, content::BrowserThread::DeleteOnIOThread> { public: + // Provides notification of when the OS level user agent settings + // are changed. class DefaultClientObserver : public ShellIntegration::DefaultWebClientObserver { public: @@ -59,9 +60,9 @@ class ProtocolHandlerRegistry DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver); }; - // TODO(koz): Refactor this to eliminate the unnecessary virtuals. All that - // should be needed is a way to ensure that the list of websafe protocols is - // updated. + // |Delegate| provides an interface for interacting asynchronously + // with the underlying OS for the purposes of registering Chrome + // as the default handler for specific protocols. class Delegate { public: virtual ~Delegate(); @@ -83,7 +84,14 @@ class ProtocolHandlerRegistry typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap; typedef std::vector<DefaultClientObserver*> DefaultClientObserverList; + // Creates a new instance. Assumes ownership of |delegate|. ProtocolHandlerRegistry(Profile* profile, Delegate* delegate); + virtual ~ProtocolHandlerRegistry(); + + // Returns a net::URLRequestJobFactory::Interceptor suitable + // for use on the IO thread, but is initialized on the UI thread. + // Callers assume responsibility for deleting this object. + net::URLRequestJobFactory::Interceptor* CreateURLInterceptor(); // Called when a site tries to register as a protocol handler. If the request // can be handled silently by the registry - either to ignore the request @@ -116,8 +124,10 @@ class ProtocolHandlerRegistry // Returns true if this handler is the default handler for its protocol. bool IsDefault(const ProtocolHandler& handler) const; - // Loads a user's registered protocol handlers. - void Load(); + // Initializes default protocol settings and loads them from prefs. + // This method must be called to complete initialization of the + // registry after creation, and prior to use. + void InitProtocolSettings(); // Returns the offset in the list of handlers for a protocol of the default // handler for that protocol. @@ -155,10 +165,6 @@ class ProtocolHandlerRegistry // Returns true if the protocol has a default protocol handler. bool IsHandledProtocol(const std::string& scheme) const; - // Returns true if the protocol has a default protocol handler. - // Should be called only from the IO thread. - bool IsHandledProtocolIO(const std::string& scheme) const; - // Removes the given protocol handler from the registry. void RemoveHandler(const ProtocolHandler& handler); @@ -169,10 +175,6 @@ class ProtocolHandlerRegistry // exists. const ProtocolHandler& GetHandlerFor(const std::string& scheme) const; - // Creates a URL request job for the given request if there is a matching - // protocol handler, returns NULL otherwise. - net::URLRequestJob* MaybeCreateJob(net::URLRequest* request) const; - // Puts this registry in the enabled state - registered protocol handlers // will handle requests. void Enable(); @@ -183,7 +185,7 @@ class ProtocolHandlerRegistry // This is called by the UI thread when the system is shutting down. This // does finalization which must be done on the UI thread. - void Finalize(); + virtual void Shutdown() OVERRIDE; // Registers the preferences that we store registered protocol handlers in. static void RegisterPrefs(PrefService* prefService); @@ -198,31 +200,21 @@ class ProtocolHandlerRegistry friend class base::DeleteHelper<ProtocolHandlerRegistry>; friend struct content::BrowserThread::DeleteOnThread< content::BrowserThread::IO>; + + // for access to InstallDefaultsForChromeOS + friend class ProtocolHandlerRegistryFactory; + friend class ProtocolHandlerRegistryTest; friend class RegisterProtocolHandlerBrowserTest; - ~ProtocolHandlerRegistry(); + // Forward declaration of the internal implementation classes. + class Core; + class URLInterceptor; // Puts the given handler at the top of the list of handlers for its // protocol. void PromoteHandler(const ProtocolHandler& handler); - // Clears the default for the provided protocol. - // Should be called only from the IO thread. - void ClearDefaultIO(const std::string& scheme); - - // Makes this ProtocolHandler the default handler for its protocol. - // Should be called only from the IO thread. - void SetDefaultIO(const ProtocolHandler& handler); - - // Indicate that the registry has been enabled in the IO thread's copy of the - // data. - void EnableIO() { enabled_io_ = true; } - - // Indicate that the registry has been disabled in the IO thread's copy of - // the data. - void DisableIO() { enabled_io_ = false; } - // Saves a user's registered protocol handlers. void Save(); @@ -230,6 +222,10 @@ class ProtocolHandlerRegistry // or NULL if there are none. const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const; + // Install default protocol handlers for chromeos which must be done + // prior to calling InitProtocolSettings. + void InstallDefaultsForChromeOS(); + // Makes this ProtocolHandler the default handler for its protocol. void SetDefault(const ProtocolHandler& handler); @@ -277,9 +273,6 @@ class ProtocolHandlerRegistry // requests. bool enabled_; - // Copy of enabled_ that is only accessed on the IO thread. - bool enabled_io_; - // Whether or not we are loading. bool is_loading_; @@ -287,10 +280,11 @@ class ProtocolHandlerRegistry // AddPredefinedHandler will be rejected. bool is_loaded_; - DefaultClientObserverList default_client_observers_; + // Copy of registry data for use on the IO thread. Changes to the registry + // are posted to the IO thread where updates are applied to this object. + scoped_refptr<Core> core_; - // Copy of default_handlers_ that is only accessed on the IO thread. - ProtocolHandlerMap default_handlers_io_; + DefaultClientObserverList default_client_observers_; DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry); }; diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_factory.cc b/chrome/browser/custom_handlers/protocol_handler_registry_factory.cc new file mode 100644 index 0000000..8da041b --- /dev/null +++ b/chrome/browser/custom_handlers/protocol_handler_registry_factory.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" + +#include "base/memory/singleton.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/extensions/extension_system_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_dependency_manager.h" + +// static +ProtocolHandlerRegistryFactory* ProtocolHandlerRegistryFactory::GetInstance() { + return Singleton<ProtocolHandlerRegistryFactory>::get(); +} + +// static +ProtocolHandlerRegistry* ProtocolHandlerRegistryFactory::GetForProfile( + Profile* profile) { + return static_cast<ProtocolHandlerRegistry*>( + GetInstance()->GetServiceForProfile(profile, true)); +} + +ProtocolHandlerRegistryFactory::ProtocolHandlerRegistryFactory() + : ProfileKeyedServiceFactory("ProtocolHandlerRegistry", + ProfileDependencyManager::GetInstance()) { +} + +ProtocolHandlerRegistryFactory::~ProtocolHandlerRegistryFactory() { +} + +// Will be created when initializing profile_io_data, so we might +// as well have the framework create this along with other +// PKSs to preserve orderly civic conduct :) +bool ProtocolHandlerRegistryFactory::ServiceIsCreatedWithProfile() { + return true; +} + +// Allows the produced registry to be used in incognito mode. +bool ProtocolHandlerRegistryFactory::ServiceRedirectedInIncognito() { + return true; +} + +// Do not create this service for tests. MANY tests will fail +// due to the threading requirements of this service. ALSO, +// not creating this increases test isolation (which is GOOD!) +bool ProtocolHandlerRegistryFactory::ServiceIsNULLWhileTesting() { + return true; +} + +ProfileKeyedService* ProtocolHandlerRegistryFactory::BuildServiceInstanceFor( + Profile* profile) const { + ProtocolHandlerRegistry* registry = new ProtocolHandlerRegistry( + profile, new ProtocolHandlerRegistry::Delegate()); + +#if defined(OS_CHROMEOS) + // If installing defaults, they must be installed prior calling + // InitProtocolSettings + registry->InstallDefaultsForChromeOS(); +#endif + + // Must be called as a part of the creation process. + registry->InitProtocolSettings(); + + return registry; +} diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_factory.h b/chrome/browser/custom_handlers/protocol_handler_registry_factory.h new file mode 100644 index 0000000..343303f --- /dev/null +++ b/chrome/browser/custom_handlers/protocol_handler_registry_factory.h @@ -0,0 +1,47 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_FACTORY_H_ +#define CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_FACTORY_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "chrome/browser/profiles/profile_keyed_service_factory.h" + +class Profile; +class ProtocolHandlerRegistry; +template <typename T> struct DefaultSingletonTraits; + +// Singleton that owns all ProtocolHandlerRegistrys and associates them with +// Profiles. Listens for the Profile's destruction notification and cleans up +// the associated ProtocolHandlerRegistry. +class ProtocolHandlerRegistryFactory : public ProfileKeyedServiceFactory { + public: + // Returns the singleton instance of the ProtocolHandlerRegistryFactory. + static ProtocolHandlerRegistryFactory* GetInstance(); + + // Returns the ProtocolHandlerRegistry that provides intent registration for + // |profile|. Ownership stays with this factory object. + static ProtocolHandlerRegistry* GetForProfile(Profile* profile); + + protected: + // ProfileKeyedServiceFactory implementation. + virtual bool ServiceIsCreatedWithProfile() OVERRIDE; + virtual bool ServiceRedirectedInIncognito() OVERRIDE; + virtual bool ServiceIsNULLWhileTesting() OVERRIDE; + + private: + friend struct DefaultSingletonTraits<ProtocolHandlerRegistryFactory>; + + ProtocolHandlerRegistryFactory(); + virtual ~ProtocolHandlerRegistryFactory(); + + // ProfileKeyedServiceFactory implementation. + virtual ProfileKeyedService* BuildServiceInstanceFor( + Profile* profile) const OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistryFactory); +}; + +#endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_FACTORY_H_ diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc index 1330661..26512b5 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc +++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc @@ -8,6 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" +#include "base/synchronization/waitable_event.h" #include "base/utf_string_conversions.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/custom_handlers/protocol_handler.h" @@ -21,11 +22,56 @@ #include "content/public/test/test_renderer_host.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" +#include "testing/gtest/include/gtest/gtest.h" using content::BrowserThread; namespace { +void AssertInterceptedIO( + const GURL& url, + net::URLRequestJobFactory::Interceptor* interceptor) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + net::URLRequestContext context; + net::URLRequest request(url, NULL, &context); + scoped_refptr<net::URLRequestJob> job = interceptor->MaybeIntercept(&request); + ASSERT_TRUE(job.get() != NULL); +} + +void AssertIntercepted( + const GURL& url, + net::URLRequestJobFactory::Interceptor* interceptor) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + BrowserThread::PostTask(BrowserThread::IO, + FROM_HERE, + base::Bind(AssertInterceptedIO, + url, + base::Unretained(interceptor))); + MessageLoop::current()->RunAllPending(); +} + +void AssertWillHandleIO( + const std::string& scheme, + bool expected, + net::URLRequestJobFactory::Interceptor* interceptor) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + ASSERT_EQ(expected, interceptor->WillHandleProtocol(scheme)); +} + +void AssertWillHandle( + const std::string& scheme, + bool expected, + net::URLRequestJobFactory::Interceptor* interceptor) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + BrowserThread::PostTask(BrowserThread::IO, + FROM_HERE, + base::Bind(AssertWillHandleIO, + scheme, + expected, + base::Unretained(interceptor))); + MessageLoop::current()->RunAllPending(); +} + class FakeDelegate : public ProtocolHandlerRegistry::Delegate { public: FakeDelegate() : force_os_failure_(false) {} @@ -174,7 +220,7 @@ class QueryProtocolHandlerOnChange public: QueryProtocolHandlerOnChange(Profile* profile, ProtocolHandlerRegistry* registry) - : registry_(registry), + : local_registry_(registry), called_(false), notification_registrar_() { notification_registrar_.Add(this, @@ -186,26 +232,53 @@ class QueryProtocolHandlerOnChange const content::NotificationSource& source, const content::NotificationDetails& details) { std::vector<std::string> output; - registry_->GetRegisteredProtocols(&output); + local_registry_->GetRegisteredProtocols(&output); called_ = true; } - ProtocolHandlerRegistry* registry_; + ProtocolHandlerRegistry* local_registry_; bool called_; content::NotificationRegistrar notification_registrar_; }; +// URLRequest DCHECKS that the current MessageLoop is IO. It does this because +// it can't check the thread id (since net can't depend on content.) We want +// to harness our tests so all threads use the same loop allowing us to +// guarantee all messages are processed.) By overriding the IsType method +// we basically ignore the supplied message loop type, and instead infer +// our type based on the current thread. GO DEPENDENCY INJECTION! +class TestMessageLoop : public MessageLoop { + public: + TestMessageLoop() : MessageLoop(MessageLoop::TYPE_DEFAULT) {} + ~TestMessageLoop() {} + virtual bool IsType(MessageLoop::Type type) const OVERRIDE { + switch (type) { + case MessageLoop::TYPE_UI: + return BrowserThread::CurrentlyOn(BrowserThread::UI); + case MessageLoop::TYPE_IO: + return BrowserThread::CurrentlyOn(BrowserThread::IO); + case MessageLoop::TYPE_DEFAULT: + return !BrowserThread::CurrentlyOn(BrowserThread::UI) && + !BrowserThread::CurrentlyOn(BrowserThread::IO); + } + return false; + } +}; + } // namespace class ProtocolHandlerRegistryTest : public testing::Test { protected: ProtocolHandlerRegistryTest() - : test_protocol_handler_(CreateProtocolHandler("test", "test")) {} + : ui_thread_(BrowserThread::UI, &loop_), + file_thread_(BrowserThread::FILE, &loop_), + io_thread_(BrowserThread::IO, &loop_), + test_protocol_handler_(CreateProtocolHandler("test", "test")) {} FakeDelegate* delegate() const { return delegate_; } + ProtocolHandlerRegistry* registry() { return registry_.get(); } TestingProfile* profile() const { return profile_.get(); } PrefService* pref_service() const { return profile_->GetPrefs(); } - ProtocolHandlerRegistry* registry() const { return registry_.get(); } const ProtocolHandler& test_protocol_handler() const { return test_protocol_handler_; } @@ -223,68 +296,48 @@ class ProtocolHandlerRegistryTest : public testing::Test { name); } - void ReloadProtocolHandlerRegistry() { - delegate_ = new FakeDelegate(); - registry_->Finalize(); - registry_ = NULL; - registry_ = new ProtocolHandlerRegistry(profile(), delegate()); - registry_->Load(); + void RecreateRegistry(bool initialize) { + TeadDownRegistry(); + SetUpRegistry(initialize); } - void ReloadProtocolHandlerRegistryAndInstallDefaultHandler() { + // Returns a new registry, initializing it if |initialize| is true. + // Caller assumes ownership for the object + void SetUpRegistry(bool initialize) { delegate_ = new FakeDelegate(); - registry_->Finalize(); - registry_ = NULL; - registry_ = new ProtocolHandlerRegistry(profile(), delegate()); - registry_->AddPredefinedHandler(CreateProtocolHandler( - "test", GURL("http://test.com/%s"), "Test")); - registry_->Load(); + registry_.reset(new ProtocolHandlerRegistry(profile(), delegate())); + if (initialize) registry_->InitProtocolSettings(); } - virtual void SetUp() { - ui_message_loop_.reset(new MessageLoopForUI()); - ui_thread_.reset(new content::TestBrowserThread(BrowserThread::UI, - MessageLoop::current())); - io_thread_.reset(new content::TestBrowserThread(BrowserThread::IO)); - io_thread_->StartIOThread(); - - file_thread_.reset(new content::TestBrowserThread(BrowserThread::FILE)); - file_thread_->Start(); + void TeadDownRegistry() { + registry_->Shutdown(); + registry_.reset(); + // Registry owns the delegate_ it handles deletion of that object. + } + virtual void SetUp() { profile_.reset(new TestingProfile()); profile_->SetPrefService(new TestingPrefService()); - delegate_ = new FakeDelegate(); - registry_ = new ProtocolHandlerRegistry(profile(), delegate()); - registry_->Load(); + SetUpRegistry(true); test_protocol_handler_ = CreateProtocolHandler("test", GURL("http://test.com/%s"), "Test"); - ProtocolHandlerRegistry::RegisterPrefs(pref_service()); } virtual void TearDown() { - registry_->Finalize(); - registry_ = NULL; - io_thread_->Stop(); - io_thread_.reset(NULL); - file_thread_->Stop(); - file_thread_.reset(NULL); - ui_thread_.reset(NULL); - ui_message_loop_.reset(NULL); + TeadDownRegistry(); } - bool enabled_io() { - return registry()->enabled_io_; - } + TestMessageLoop loop_; - scoped_ptr<MessageLoopForUI> ui_message_loop_; - scoped_ptr<content::TestBrowserThread> ui_thread_; - scoped_ptr<content::TestBrowserThread> io_thread_; - scoped_ptr<content::TestBrowserThread> file_thread_; + private: + content::TestBrowserThread ui_thread_; + content::TestBrowserThread file_thread_; + content::TestBrowserThread io_thread_; - FakeDelegate* delegate_; scoped_ptr<TestingProfile> profile_; - scoped_refptr<ProtocolHandlerRegistry> registry_; + FakeDelegate* delegate_; // Registry assumes ownership of delegate_. + scoped_ptr<ProtocolHandlerRegistry> registry_; ProtocolHandler test_protocol_handler_; }; @@ -383,7 +436,7 @@ TEST_F(ProtocolHandlerRegistryTest, SaveAndLoad) { ASSERT_TRUE(registry()->IsHandledProtocol("test")); ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler)); delegate()->Reset(); - ReloadProtocolHandlerRegistry(); + RecreateRegistry(true); ASSERT_TRUE(registry()->IsHandledProtocol("test")); ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler)); } @@ -469,14 +522,14 @@ TEST_F(ProtocolHandlerRegistryTest, TestDefaultSaveLoad) { registry()->OnAcceptRegisterProtocolHandler(ph2); registry()->Disable(); - ReloadProtocolHandlerRegistry(); + RecreateRegistry(true); ASSERT_FALSE(registry()->enabled()); registry()->Enable(); ASSERT_FALSE(registry()->IsDefault(ph1)); ASSERT_TRUE(registry()->IsDefault(ph2)); - ReloadProtocolHandlerRegistry(); + RecreateRegistry(true); ASSERT_TRUE(registry()->enabled()); } @@ -636,6 +689,10 @@ TEST_F(ProtocolHandlerRegistryTest, TestDisablePreventsHandling) { ASSERT_FALSE(registry()->IsHandledProtocol("test")); } +// TODO(smckay): This is much more appropriately an integration +// test. Make that so, then update the +// ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully +// isolate this test from the FILE thread. TEST_F(ProtocolHandlerRegistryTest, TestOSRegistration) { ProtocolHandler ph_do1 = CreateProtocolHandler("do", "test1"); ProtocolHandler ph_do2 = CreateProtocolHandler("do", "test2"); @@ -646,7 +703,7 @@ TEST_F(ProtocolHandlerRegistryTest, TestOSRegistration) { registry()->OnAcceptRegisterProtocolHandler(ph_do1); registry()->OnDenyRegisterProtocolHandler(ph_dont); - MessageLoop::current()->Run(); + MessageLoop::current()->Run(); // FILE thread needs to run. ASSERT_TRUE(delegate()->IsFakeRegisteredWithOS("do")); ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("dont")); @@ -664,6 +721,10 @@ TEST_F(ProtocolHandlerRegistryTest, TestOSRegistration) { #define MAYBE_TestOSRegistrationFailure TestOSRegistrationFailure #endif +// TODO(smckay): This is much more appropriately an integration +// test. Make that so, then update the +// ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully +// isolate this test from the FILE thread. TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestOSRegistrationFailure) { ProtocolHandler ph_do = CreateProtocolHandler("do", "test1"); ProtocolHandler ph_dont = CreateProtocolHandler("dont", "test"); @@ -672,40 +733,24 @@ TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestOSRegistrationFailure) { ASSERT_FALSE(registry()->IsHandledProtocol("dont")); registry()->OnAcceptRegisterProtocolHandler(ph_do); - MessageLoop::current()->Run(); + MessageLoop::current()->Run(); // FILE thread needs to run. delegate()->set_force_os_failure(true); registry()->OnAcceptRegisterProtocolHandler(ph_dont); - MessageLoop::current()->Run(); + MessageLoop::current()->Run(); // FILE thread needs to run. ASSERT_TRUE(registry()->IsHandledProtocol("do")); ASSERT_EQ(static_cast<size_t>(1), registry()->GetHandlersFor("do").size()); ASSERT_FALSE(registry()->IsHandledProtocol("dont")); ASSERT_EQ(static_cast<size_t>(1), registry()->GetHandlersFor("dont").size()); } -static void MakeRequest(const GURL& url, ProtocolHandlerRegistry* registry) { - net::URLRequestContext context; - net::URLRequest request(url, NULL, &context); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - MessageLoop::QuitClosure()); - scoped_refptr<net::URLRequestJob> job(registry->MaybeCreateJob(&request)); - ASSERT_TRUE(job.get() != NULL); -} - TEST_F(ProtocolHandlerRegistryTest, TestMaybeCreateTaskWorksFromIOThread) { ProtocolHandler ph1 = CreateProtocolHandler("mailto", "test1"); registry()->OnAcceptRegisterProtocolHandler(ph1); GURL url("mailto:someone@something.com"); - scoped_refptr<ProtocolHandlerRegistry> r(registry()); - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(MakeRequest, url, r)); - MessageLoop::current()->Run(); -} + net::URLRequestJobFactory::Interceptor* interceptor = + registry()->CreateURLInterceptor(); -static void CheckIsHandled(const std::string& scheme, bool expected, - ProtocolHandlerRegistry* registry) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - MessageLoop::QuitClosure()); - ASSERT_EQ(expected, registry->IsHandledProtocolIO(scheme)); + AssertIntercepted(url, interceptor); } TEST_F(ProtocolHandlerRegistryTest, @@ -713,11 +758,10 @@ TEST_F(ProtocolHandlerRegistryTest, std::string scheme("mailto"); ProtocolHandler ph1 = CreateProtocolHandler(scheme, "test1"); registry()->OnAcceptRegisterProtocolHandler(ph1); - scoped_refptr<ProtocolHandlerRegistry> r(registry()); - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(CheckIsHandled, scheme, true, r)); + net::URLRequestJobFactory::Interceptor* interceptor = + registry()->CreateURLInterceptor(); + + AssertWillHandle(scheme, true, interceptor); } TEST_F(ProtocolHandlerRegistryTest, TestRemovingDefaultFallsBackToOldDefault) { @@ -761,26 +805,23 @@ TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestClearDefaultGetsPropagatedToIO) { ProtocolHandler ph1 = CreateProtocolHandler(scheme, "test1"); registry()->OnAcceptRegisterProtocolHandler(ph1); registry()->ClearDefault(scheme); - scoped_refptr<ProtocolHandlerRegistry> r(registry()); + net::URLRequestJobFactory::Interceptor* interceptor = + registry()->CreateURLInterceptor(); - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(CheckIsHandled, scheme, false, r)); -} - -static void QuitUILoop() { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - MessageLoop::QuitClosure()); + AssertWillHandle(scheme, false, interceptor); } TEST_F(ProtocolHandlerRegistryTest, TestLoadEnabledGetsPropogatedToIO) { + std::string mailto("mailto"); + ProtocolHandler ph1 = CreateProtocolHandler(mailto, "MailtoHandler"); + registry()->OnAcceptRegisterProtocolHandler(ph1); + + net::URLRequestJobFactory::Interceptor* interceptor = + registry()->CreateURLInterceptor(); + AssertWillHandle(mailto, true, interceptor); registry()->Disable(); - ReloadProtocolHandlerRegistry(); - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(QuitUILoop)); - MessageLoop::current()->Run(); - ASSERT_FALSE(enabled_io()); + AssertWillHandle(mailto, false, interceptor); + delete interceptor; } TEST_F(ProtocolHandlerRegistryTest, TestReplaceHandler) { @@ -844,7 +885,10 @@ TEST_F(ProtocolHandlerRegistryTest, TestIsSameOrigin) { } TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestInstallDefaultHandler) { - ReloadProtocolHandlerRegistryAndInstallDefaultHandler(); + RecreateRegistry(false); + registry()->AddPredefinedHandler(CreateProtocolHandler( + "test", GURL("http://test.com/%s"), "Test")); + registry()->InitProtocolSettings(); std::vector<std::string> protocols; registry()->GetRegisteredProtocols(&protocols); ASSERT_EQ(static_cast<size_t>(1), protocols.size()); diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index 957faa6..a75398e 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc @@ -375,10 +375,6 @@ void OffTheRecordProfileImpl::InitPromoResources() { NOTREACHED(); } -void OffTheRecordProfileImpl::InitRegisteredProtocolHandlers() { - NOTREACHED(); -} - FilePath OffTheRecordProfileImpl::last_selected_directory() { const FilePath& directory = last_selected_directory_; if (directory.empty()) { diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h index 3c05723..fbfbdb2 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.h +++ b/chrome/browser/profiles/off_the_record_profile_impl.h @@ -66,7 +66,6 @@ class OffTheRecordProfileImpl : public Profile, virtual history::TopSites* GetTopSites() OVERRIDE; virtual void MarkAsCleanShutdown() OVERRIDE; virtual void InitPromoResources() OVERRIDE; - virtual void InitRegisteredProtocolHandlers() OVERRIDE; virtual FilePath last_selected_directory() OVERRIDE; virtual void set_last_selected_directory(const FilePath& path) OVERRIDE; virtual bool WasCreatedByVersionOrLater(const std::string& version) OVERRIDE; diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index 7c73363..e9c1f92 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h @@ -283,6 +283,7 @@ class Profile : public content::BrowserContext { virtual BookmarkModel* GetBookmarkModel() = 0; // Returns the ProtocolHandlerRegistry, creating if not yet created. + // TODO(smckay): replace this with access via ProtocolHandlerRegistryFactory. virtual ProtocolHandlerRegistry* GetProtocolHandlerRegistry() = 0; // Return whether 2 profiles are the same. 2 profiles are the same if they @@ -306,10 +307,6 @@ class Profile : public content::BrowserContext { // Start up service that gathers data from a promo resource feed. virtual void InitPromoResources() = 0; - // Register URLRequestFactories for protocols registered with - // registerProtocolHandler. - virtual void InitRegisteredProtocolHandlers() = 0; - // Returns the last directory that was chosen for uploading or opening a file. virtual FilePath last_selected_directory() = 0; virtual void set_last_selected_directory(const FilePath& path) = 0; diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc index 05cbcc4..1c2a856 100644 --- a/chrome/browser/profiles/profile_dependency_manager.cc +++ b/chrome/browser/profiles/profile_dependency_manager.cc @@ -13,6 +13,7 @@ #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/captive_portal/captive_portal_service_factory.h" #include "chrome/browser/content_settings/cookie_settings.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/extensions/api/commands/command_service_factory.h" #include "chrome/browser/extensions/api/discovery/suggested_links_registry_factory.h" @@ -235,6 +236,7 @@ void ProfileDependencyManager::AssertFactoriesBuilt() { prerender::PrerenderManagerFactory::GetInstance(); prerender::PrerenderLinkManagerFactory::GetInstance(); ProfileSyncServiceFactory::GetInstance(); + ProtocolHandlerRegistryFactory::GetInstance(); #if defined(ENABLE_PROTECTOR_SERVICE) protector::ProtectorServiceFactory::GetInstance(); #endif diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 36e24cb..3d7d158 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -27,6 +27,7 @@ #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/download/download_service.h" #include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/extensions/extension_event_router.h" @@ -350,8 +351,6 @@ void ProfileImpl::DoFinalInit(bool is_new_profile) { g_browser_process->background_mode_manager()->RegisterProfile(this); } - InitRegisteredProtocolHandlers(); - InstantController::RecordMetrics(this); FilePath cookie_path = GetPath(); @@ -453,33 +452,6 @@ void ProfileImpl::InitPromoResources() { promo_resource_service_->StartAfterDelay(); } -void ProfileImpl::InitRegisteredProtocolHandlers() { - if (protocol_handler_registry_) - return; - protocol_handler_registry_ = new ProtocolHandlerRegistry(this, - new ProtocolHandlerRegistry::Delegate()); - - // Install predefined protocol handlers. - InstallDefaultProtocolHandlers(); - - protocol_handler_registry_->Load(); -} - -void ProfileImpl::InstallDefaultProtocolHandlers() { -#if defined(OS_CHROMEOS) - protocol_handler_registry_->AddPredefinedHandler( - ProtocolHandler::CreateProtocolHandler( - "mailto", - GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_MAILTO_HANDLER_URL)), - l10n_util::GetStringUTF16(IDS_GOOGLE_MAILTO_HANDLER_NAME))); - protocol_handler_registry_->AddPredefinedHandler( - ProtocolHandler::CreateProtocolHandler( - "webcal", - GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_WEBCAL_HANDLER_URL)), - l10n_util::GetStringUTF16(IDS_GOOGLE_WEBCAL_HANDLER_NAME))); -#endif -} - FilePath ProfileImpl::last_selected_directory() { return GetPrefs()->GetFilePath(prefs::kSelectFileLastDirectory); } @@ -534,9 +506,6 @@ ProfileImpl::~ProfileImpl() { if (pref_proxy_config_tracker_.get()) pref_proxy_config_tracker_->DetachFromPrefService(); - if (protocol_handler_registry_) - protocol_handler_registry_->Finalize(); - if (host_content_settings_map_) host_content_settings_map_->ShutdownOnUIThread(); @@ -812,7 +781,11 @@ BookmarkModel* ProfileImpl::GetBookmarkModel() { } ProtocolHandlerRegistry* ProfileImpl::GetProtocolHandlerRegistry() { - return protocol_handler_registry_.get(); + // TODO(smckay): Update all existing callers to use + // ProtocolHandlerRegistryFactory. Once that's done, this method + // can be nuked from Profile and ProfileImpl. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + return ProtocolHandlerRegistryFactory::GetForProfile(this); } bool ProfileImpl::IsSameProfile(Profile* profile) { diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index cbd6e65..514e532 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -102,7 +102,6 @@ class ProfileImpl : public Profile, virtual base::Time GetStartTime() const OVERRIDE; virtual void MarkAsCleanShutdown() OVERRIDE; virtual void InitPromoResources() OVERRIDE; - virtual void InitRegisteredProtocolHandlers() OVERRIDE; virtual FilePath last_selected_directory() OVERRIDE; virtual void set_last_selected_directory(const FilePath& path) OVERRIDE; virtual chrome_browser_net::Predictor* GetNetworkPredictor() OVERRIDE; @@ -146,9 +145,6 @@ class ProfileImpl : public Profile, void InitHostZoomMap(); - // The installation of any pre-defined protocol handlers. - void InstallDefaultProtocolHandlers(); - // Does final prefs initialization and calls Init(). void OnPrefsLoaded(bool success); @@ -206,13 +202,8 @@ class ProfileImpl : public Profile, scoped_refptr<ExtensionSpecialStoragePolicy> extension_special_storage_policy_; scoped_ptr<NetPrefObserver> net_pref_observer_; - scoped_refptr<PromoResourceService> promo_resource_service_; - - scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry_; - scoped_ptr<SSLConfigServiceManager> ssl_config_service_manager_; - scoped_refptr<HostContentSettingsMap> host_content_settings_map_; scoped_refptr<content::GeolocationPermissionContext> geolocation_permission_context_; diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 494821a..88da911 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -20,6 +20,7 @@ #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/download/download_service.h" #include "chrome/browser/download/download_service_factory.h" #include "chrome/browser/extensions/extension_info_map.h" @@ -117,42 +118,6 @@ class ChromeCookieMonsterDelegate : public net::CookieMonster::Delegate { const base::Callback<Profile*(void)> profile_getter_; }; -class ProtocolHandlerRegistryInterceptor - : public net::URLRequestJobFactory::Interceptor { - public: - explicit ProtocolHandlerRegistryInterceptor( - ProtocolHandlerRegistry* protocol_handler_registry) - : protocol_handler_registry_(protocol_handler_registry) { - DCHECK(protocol_handler_registry_); - } - - virtual ~ProtocolHandlerRegistryInterceptor() {} - - virtual net::URLRequestJob* MaybeIntercept( - net::URLRequest* request) const OVERRIDE { - return protocol_handler_registry_->MaybeCreateJob(request); - } - - virtual bool WillHandleProtocol(const std::string& protocol) const { - return protocol_handler_registry_->IsHandledProtocolIO(protocol); - } - - virtual net::URLRequestJob* MaybeInterceptRedirect( - const GURL& url, net::URLRequest* request) const OVERRIDE { - return NULL; - } - - virtual net::URLRequestJob* MaybeInterceptResponse( - net::URLRequest* request) const OVERRIDE { - return NULL; - } - - private: - const scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry_; - - DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistryInterceptor); -}; - Profile* GetProfileOnUI(ProfileManager* profile_manager, Profile* profile) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(profile); @@ -215,7 +180,15 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) { DesktopNotificationServiceFactory::GetForProfile(profile); #endif - params->protocol_handler_registry = profile->GetProtocolHandlerRegistry(); + ProtocolHandlerRegistry* protocol_handler_registry = + ProtocolHandlerRegistryFactory::GetForProfile(profile); + DCHECK(protocol_handler_registry); + + // the profile instance is only available here in the InitializeOnUIThread + // method, so we create the url interceptor here, then save it for + // later delivery to the job factory in LazyInitialize + params->protocol_handler_url_interceptor.reset( + protocol_handler_registry->CreateURLInterceptor()); ChromeProxyConfigService* proxy_config_service = ProxyServiceFactory::CreateProxyConfigService(true); @@ -545,11 +518,12 @@ void ProfileIOData::SetUpJobFactoryDefaults( net::URLRequestJobFactory* job_factory) const { // NOTE(willchan): Keep these protocol handlers in sync with // ProfileIOData::IsHandledProtocol(). - if (profile_params_->protocol_handler_registry) { + + if (profile_params_->protocol_handler_url_interceptor.get()) { job_factory->AddInterceptor( - new ProtocolHandlerRegistryInterceptor( - profile_params_->protocol_handler_registry)); + profile_params_->protocol_handler_url_interceptor.release()); } + bool set_protocol = job_factory->SetProtocolHandler( chrome::kExtensionScheme, CreateExtensionProtocolHandler(is_incognito(), diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index 036a2af..b4ebf01 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h @@ -18,6 +18,7 @@ #include "chrome/browser/prefs/pref_member.h" #include "content/public/browser/resource_context.h" #include "net/cookies/cookie_monster.h" +#include "net/url_request/url_request_job_factory.h" class CookieSettings; class DesktopNotificationService; @@ -165,7 +166,13 @@ class ProfileIOData { DesktopNotificationService* notification_service; #endif - scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry; + // This pointer exists only as a means of conveying a url interceptor + // pointer from the protocol handler registry on the UI thread to the + // the URLRequestJobFactory on the IO thread. The consumer MUST take + // ownership of the object by calling release() on this pointer. + scoped_ptr<net::URLRequestJobFactory::Interceptor> + protocol_handler_url_interceptor; + // We need to initialize the ProxyConfigService from the UI thread // because on linux it relies on initializing things through gconf, // and needs to be on the main thread. diff --git a/chrome/browser/tab_contents/render_view_context_menu.h b/chrome/browser/tab_contents/render_view_context_menu.h index b7c79d3..d215e98 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.h +++ b/chrome/browser/tab_contents/render_view_context_menu.h @@ -285,7 +285,7 @@ class RenderViewContextMenu : public ui::SimpleMenuModel::Delegate, ui::SimpleMenuModel bidi_submenu_model_; ui::SimpleMenuModel protocol_handler_submenu_model_; ScopedVector<ui::SimpleMenuModel> extension_menu_models_; - scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry_; + ProtocolHandlerRegistry* protocol_handler_registry_; // An observer that handles spelling-menu items. scoped_ptr<SpellingMenuObserver> spelling_menu_observer_; diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 1437b1c..03adaa8 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc @@ -9,6 +9,7 @@ #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/favicon/favicon_tab_helper.h" #include "chrome/browser/infobars/infobar_tab_helper.h" #include "chrome/browser/prefs/pref_service.h" @@ -606,12 +607,15 @@ ContentSettingRPHBubbleModel::ContentSettingRPHBubbleModel( Delegate* delegate, TabContents* tab_contents, Profile* profile, + ProtocolHandlerRegistry* registry, ContentSettingsType content_type) : ContentSettingTitleAndLinkModel( delegate, tab_contents, profile, content_type), selected_item_(0), + registry_(registry), pending_handler_(ProtocolHandler::EmptyProtocolHandler()), previous_handler_(ProtocolHandler::EmptyProtocolHandler()) { + DCHECK_EQ(CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, content_type); TabSpecificContentSettings* content_settings = @@ -690,26 +694,22 @@ void ContentSettingRPHBubbleModel::OnRadioClicked(int radio_index) { void ContentSettingRPHBubbleModel::RegisterProtocolHandler() { // A no-op if the handler hasn't been ignored, but needed in case the user // selects sequences like register/ignore/register. - profile()->GetProtocolHandlerRegistry()->RemoveIgnoredHandler( - pending_handler_); + registry_->RemoveIgnoredHandler(pending_handler_); - profile()->GetProtocolHandlerRegistry()->OnAcceptRegisterProtocolHandler( - pending_handler_); + registry_->OnAcceptRegisterProtocolHandler(pending_handler_); tab_contents()->content_settings()->set_pending_protocol_handler_setting( CONTENT_SETTING_ALLOW); } void ContentSettingRPHBubbleModel::UnregisterProtocolHandler() { - profile()->GetProtocolHandlerRegistry()->OnDenyRegisterProtocolHandler( - pending_handler_); + registry_->OnDenyRegisterProtocolHandler(pending_handler_); tab_contents()->content_settings()->set_pending_protocol_handler_setting( CONTENT_SETTING_BLOCK); ClearOrSetPreviousHandler(); } void ContentSettingRPHBubbleModel::IgnoreProtocolHandler() { - profile()->GetProtocolHandlerRegistry()->OnIgnoreRegisterProtocolHandler( - pending_handler_); + registry_->OnIgnoreRegisterProtocolHandler(pending_handler_); tab_contents()->content_settings()->set_pending_protocol_handler_setting( CONTENT_SETTING_DEFAULT); ClearOrSetPreviousHandler(); @@ -717,11 +717,9 @@ void ContentSettingRPHBubbleModel::IgnoreProtocolHandler() { void ContentSettingRPHBubbleModel::ClearOrSetPreviousHandler() { if (previous_handler_.IsEmpty()) { - profile()->GetProtocolHandlerRegistry()->ClearDefault( - pending_handler_.protocol()); + registry_->ClearDefault(pending_handler_.protocol()); } else { - profile()->GetProtocolHandlerRegistry()->OnAcceptRegisterProtocolHandler( - previous_handler_); + registry_->OnAcceptRegisterProtocolHandler(previous_handler_); } } @@ -753,8 +751,10 @@ ContentSettingBubbleModel* profile, content_type); } if (content_type == CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) { + ProtocolHandlerRegistry* registry = + ProtocolHandlerRegistryFactory::GetForProfile(profile); return new ContentSettingRPHBubbleModel(delegate, tab_contents, profile, - content_type); + registry, content_type); } return new ContentSettingSingleRadioGroup(delegate, tab_contents, profile, content_type); diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h index 07c9773..9e4377b 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h @@ -19,6 +19,7 @@ class ContentSettingBubbleModelDelegate; class Profile; +class ProtocolHandlerRegistry; class TabContents; // This model provides data for ContentSettingBubble, and also controls @@ -158,6 +159,7 @@ class ContentSettingRPHBubbleModel : public ContentSettingTitleAndLinkModel { ContentSettingRPHBubbleModel(Delegate* delegate, TabContents* tab_contents, Profile* profile, + ProtocolHandlerRegistry* registry, ContentSettingsType content_type); virtual void OnRadioClicked(int radio_index) OVERRIDE; @@ -177,6 +179,7 @@ class ContentSettingRPHBubbleModel : public ContentSettingTitleAndLinkModel { void ClearOrSetPreviousHandler(); int selected_item_; + ProtocolHandlerRegistry* registry_; ProtocolHandler pending_handler_; ProtocolHandler previous_handler_; }; diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc index 2f3563e..334baf6 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc @@ -251,12 +251,12 @@ TEST_F(ContentSettingBubbleModelTest, RegisterProtocolHandler) { ProtocolHandler::CreateProtocolHandler("mailto", GURL("http://www.toplevel.example/"), ASCIIToUTF16("Handler"))); - scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( - ContentSettingBubbleModel::CreateContentSettingBubbleModel( - NULL, tab_contents(), profile(), - CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS)); + ContentSettingRPHBubbleModel content_setting_bubble_model( + NULL, tab_contents(), profile(), NULL, + CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS); + const ContentSettingBubbleModel::BubbleContent& bubble_content = - content_setting_bubble_model->bubble_content(); + content_setting_bubble_model.bubble_content(); EXPECT_FALSE(bubble_content.title.empty()); EXPECT_FALSE(bubble_content.radio_group.radio_items.empty()); EXPECT_TRUE(bubble_content.popup_items.empty()); @@ -295,7 +295,9 @@ class FakeDelegate : public ProtocolHandlerRegistry::Delegate { TEST_F(ContentSettingBubbleModelTest, RPHAllow) { StartIOThread(); - profile()->CreateProtocolHandlerRegistry(new FakeDelegate); + + ProtocolHandlerRegistry registry(profile(), new FakeDelegate()); + registry.InitProtocolSettings(); const GURL page_url("http://toplevel.example/"); NavigateAndCommit(page_url); @@ -306,24 +308,21 @@ TEST_F(ContentSettingBubbleModelTest, RPHAllow) { ASCIIToUTF16("Handler")); content_settings->set_pending_protocol_handler(test_handler); - scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model( - ContentSettingBubbleModel::CreateContentSettingBubbleModel( - NULL, tab_contents(), profile(), - CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS)); + ContentSettingRPHBubbleModel content_setting_bubble_model( + NULL, tab_contents(), profile(), ®istry, + CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS); { - ProtocolHandler handler = - profile()->GetProtocolHandlerRegistry()->GetHandlerFor("mailto"); + ProtocolHandler handler = registry.GetHandlerFor("mailto"); EXPECT_TRUE(handler.IsEmpty()); EXPECT_EQ(CONTENT_SETTING_DEFAULT, content_settings->pending_protocol_handler_setting()); } // "0" is the "Allow" radio button. - content_setting_bubble_model->OnRadioClicked(0); + content_setting_bubble_model.OnRadioClicked(0); { - ProtocolHandler handler = - profile()->GetProtocolHandlerRegistry()->GetHandlerFor("mailto"); + ProtocolHandler handler = registry.GetHandlerFor("mailto"); ASSERT_FALSE(handler.IsEmpty()); EXPECT_EQ(ASCIIToUTF16("Handler"), handler.title()); EXPECT_EQ(CONTENT_SETTING_ALLOW, @@ -331,40 +330,34 @@ TEST_F(ContentSettingBubbleModelTest, RPHAllow) { } // "1" is the "Deny" radio button. - content_setting_bubble_model->OnRadioClicked(1); + content_setting_bubble_model.OnRadioClicked(1); { - ProtocolHandler handler = - profile()->GetProtocolHandlerRegistry()->GetHandlerFor("mailto"); + ProtocolHandler handler = registry.GetHandlerFor("mailto"); EXPECT_TRUE(handler.IsEmpty()); EXPECT_EQ(CONTENT_SETTING_BLOCK, content_settings->pending_protocol_handler_setting()); } // "2" is the "Ignore button. - content_setting_bubble_model->OnRadioClicked(2); + content_setting_bubble_model.OnRadioClicked(2); { - ProtocolHandler handler = - profile()->GetProtocolHandlerRegistry()->GetHandlerFor("mailto"); + ProtocolHandler handler = registry.GetHandlerFor("mailto"); EXPECT_TRUE(handler.IsEmpty()); EXPECT_EQ(CONTENT_SETTING_DEFAULT, content_settings->pending_protocol_handler_setting()); - EXPECT_TRUE(profile()->GetProtocolHandlerRegistry()->IsIgnored( - test_handler)); + EXPECT_TRUE(registry.IsIgnored(test_handler)); } // "0" is the "Allow" radio button. - content_setting_bubble_model->OnRadioClicked(0); + content_setting_bubble_model.OnRadioClicked(0); { - ProtocolHandler handler = - profile()->GetProtocolHandlerRegistry()->GetHandlerFor("mailto"); + ProtocolHandler handler = registry.GetHandlerFor("mailto"); ASSERT_FALSE(handler.IsEmpty()); EXPECT_EQ(ASCIIToUTF16("Handler"), handler.title()); EXPECT_EQ(CONTENT_SETTING_ALLOW, content_settings->pending_protocol_handler_setting()); - EXPECT_FALSE(profile()->GetProtocolHandlerRegistry()->IsIgnored( - test_handler)); + EXPECT_FALSE(registry.IsIgnored(test_handler)); } - // This must be done on the UI thread. - profile()->GetProtocolHandlerRegistry()->Finalize(); + registry.Shutdown(); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 2c64d31..cd86a5b 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -973,6 +973,8 @@ 'browser/crash_upload_list_win.h', 'browser/custom_handlers/protocol_handler_registry.cc', 'browser/custom_handlers/protocol_handler_registry.h', + 'browser/custom_handlers/protocol_handler_registry_factory.cc', + 'browser/custom_handlers/protocol_handler_registry_factory.h', 'browser/custom_handlers/register_protocol_handler_infobar_delegate.cc', 'browser/custom_handlers/register_protocol_handler_infobar_delegate.h', 'browser/custom_home_pages_table_model.cc', diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 487dffa..27a2dcc 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -369,16 +369,6 @@ void TestingProfile::CreateBookmarkModel(bool delete_file) { } } -void TestingProfile::CreateProtocolHandlerRegistry() { - CreateProtocolHandlerRegistry( - new ProtocolHandlerRegistry::Delegate()); -} - -void TestingProfile::CreateProtocolHandlerRegistry( - ProtocolHandlerRegistry::Delegate* delegate) { - protocol_handler_registry_ = new ProtocolHandlerRegistry(this, delegate); -} - static scoped_refptr<RefcountedProfileKeyedService> BuildWebDataService( Profile* profile) { WebDataService* web_data_service = new WebDataService(); @@ -688,7 +678,7 @@ base::Time TestingProfile::GetStartTime() const { } ProtocolHandlerRegistry* TestingProfile::GetProtocolHandlerRegistry() { - return protocol_handler_registry_.get(); + return NULL; } FilePath TestingProfile::last_selected_directory() { diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index 79af813..58ed551 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h @@ -105,14 +105,6 @@ class TestingProfile : public Profile { // BlockUntilBookmarkModelLoaded. void CreateBookmarkModel(bool delete_file); - // Creates a ProtocolHandlerRegistry. If not invoked the protocol handler - // registry is NULL. - void CreateProtocolHandlerRegistry(); - - // Creates a ProtocolHandlerRegistry with the provided delegate. - void CreateProtocolHandlerRegistry( - ProtocolHandlerRegistry::Delegate* delegate); - // Creates a WebDataService. If not invoked, the web data service is NULL. void CreateWebDataService(); @@ -214,7 +206,6 @@ class TestingProfile : public Profile { virtual ProtocolHandlerRegistry* GetProtocolHandlerRegistry() OVERRIDE; virtual void MarkAsCleanShutdown() OVERRIDE {} virtual void InitPromoResources() OVERRIDE {} - virtual void InitRegisteredProtocolHandlers() OVERRIDE {} virtual FilePath last_selected_directory() OVERRIDE; virtual void set_last_selected_directory(const FilePath& path) OVERRIDE; @@ -269,10 +260,6 @@ class TestingProfile : public Profile { // The favicon service. Only created if CreateFaviconService is invoked. scoped_ptr<FaviconService> favicon_service_; - // The ProtocolHandlerRegistry. Only created if CreateProtocolHandlerRegistry - // is invoked. - scoped_refptr<ProtocolHandlerRegistry> protocol_handler_registry_; - // The policy service. Lazily created as a stub. scoped_ptr<policy::PolicyService> policy_service_; diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 8b82323..eac80f4b 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc @@ -157,9 +157,9 @@ URLRequest::URLRequest(const GURL& url, SIMPLE_STATS_COUNTER("URLRequestCount"); // Sanity check out environment. - DCHECK(MessageLoop::current()) << - "The current MessageLoop must exist"; - DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << + DCHECK(MessageLoop::current()) << "The current MessageLoop must exist"; + + DCHECK(MessageLoop::current()->IsType(MessageLoop::TYPE_IO)) << "" "The current MessageLoop must be TYPE_IO"; CHECK(context); |