summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsmckay@chromium.org <smckay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-21 00:26:32 +0000
committersmckay@chromium.org <smckay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-21 00:26:32 +0000
commitab563ff06585024ba472e35a2944ed787202101c (patch)
treec2699a2f1a6224d93f14e19283db7a958d2d4ed9
parent1f4bb9e8d93accfc080f62b419ca312d1f48f11e (diff)
downloadchromium_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
-rw-r--r--base/message_loop.cc4
-rw-r--r--base/message_loop.h4
-rw-r--r--base/message_loop_unittest.cc7
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry.cc272
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry.h74
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry_factory.cc67
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry_factory.h47
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc232
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.cc4
-rw-r--r--chrome/browser/profiles/off_the_record_profile_impl.h1
-rw-r--r--chrome/browser/profiles/profile.h5
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.cc2
-rw-r--r--chrome/browser/profiles/profile_impl.cc39
-rw-r--r--chrome/browser/profiles/profile_impl.h9
-rw-r--r--chrome/browser/profiles/profile_io_data.cc54
-rw-r--r--chrome/browser/profiles/profile_io_data.h9
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.h2
-rw-r--r--chrome/browser/ui/content_settings/content_setting_bubble_model.cc26
-rw-r--r--chrome/browser/ui/content_settings/content_setting_bubble_model.h3
-rw-r--r--chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc53
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/test/base/testing_profile.cc12
-rw-r--r--chrome/test/base/testing_profile.h13
-rw-r--r--net/url_request/url_request.cc6
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(), &registry,
+ 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);