summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkoz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-02 18:54:49 +0000
committerkoz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-02 18:54:49 +0000
commitfd8ca5208c2035467253b5f8613c46745688d655 (patch)
tree2b9eb7d357027f3bf2ca99d462b39bcf83bb696a /chrome
parent695b5bbbd76715aec3a3310529f4aeb4c8b32f43 (diff)
downloadchromium_src-fd8ca5208c2035467253b5f8613c46745688d655.zip
chromium_src-fd8ca5208c2035467253b5f8613c46745688d655.tar.gz
chromium_src-fd8ca5208c2035467253b5f8613c46745688d655.tar.bz2
Add unit test and 'ignore' functionality to ProtocolHandlerRegistry.
When we change the infobar to make use of this functionality it will make it feasible for sites to make registerProtocolHandler calls on load, instead of in response to a user action. BUG= TEST=Unit test provided. Review URL: http://codereview.chromium.org/6878094 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83751 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry.cc227
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry.h83
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc134
-rw-r--r--chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc1
-rw-r--r--chrome/browser/profiles/profile_impl.cc3
-rw-r--r--chrome/browser/ui/tab_contents/tab_contents_wrapper.cc6
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/pref_names.cc14
-rw-r--r--chrome/common/pref_names.h2
-rw-r--r--chrome/test/testing_profile.cc3
10 files changed, 426 insertions, 48 deletions
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index 067c21a..1e93ca57 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -5,8 +5,11 @@
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "base/memory/scoped_ptr.h"
+#include "base/stl_util-inl.h"
+#include "chrome/browser/custom_handlers/protocol_handler.h"
#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
#include "chrome/browser/net/chrome_url_request_context.h"
+#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/pref_names.h"
#include "content/browser/child_process_security_policy.h"
#include "net/base/network_delegate.h"
@@ -15,36 +18,104 @@
// ProtocolHandlerRegistry -----------------------------------------------------
-ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile)
- :profile_(profile) {
+ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile,
+ Delegate* delegate)
+ : profile_(profile),
+ delegate_(delegate),
+ enabled_(true) {
+}
+
+ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {
+ STLDeleteContainerPairSecondPointers(protocol_handlers_.begin(),
+ protocol_handlers_.end());
+ STLDeleteContainerPointers(ignored_protocol_handlers_.begin(),
+ ignored_protocol_handlers_.end());
+}
+
+static void RemoveAndDelete(ProtocolHandlerMap& handlers,
+ const std::string& scheme) {
+ ProtocolHandlerMap::iterator p = handlers.find(scheme);
+ if (p != handlers.end()) {
+ ProtocolHandler* removed_handler = p->second;
+ handlers.erase(p);
+ delete removed_handler;
+ }
}
void ProtocolHandlerRegistry::RegisterProtocolHandler(
ProtocolHandler* handler) {
- if (protocolHandlers_.find(handler->protocol()) == protocolHandlers_.end()) {
- ChildProcessSecurityPolicy* policy =
- ChildProcessSecurityPolicy::GetInstance();
- if (!policy->IsWebSafeScheme(handler->protocol())) {
- policy->RegisterWebSafeScheme(handler->protocol());
+ DCHECK(CanSchemeBeOverridden(handler->protocol()));
+ if (enabled_) {
+ delegate_->RegisterExternalHandler(handler->protocol());
+ }
+ RemoveAndDelete(protocol_handlers_, handler->protocol());
+ protocol_handlers_[handler->protocol()] = handler;
+}
+
+void ProtocolHandlerRegistry::IgnoreProtocolHandler(ProtocolHandler* handler) {
+ ignored_protocol_handlers_.push_back(handler);
+}
+
+void ProtocolHandlerRegistry::Enable() {
+ if (enabled_) {
+ return;
+ }
+ enabled_ = true;
+ for (ProtocolHandlerMap::const_iterator p = protocol_handlers_.begin();
+ p != protocol_handlers_.end(); p++) {
+ delegate_->RegisterExternalHandler(p->first);
+ }
+}
+
+void ProtocolHandlerRegistry::Disable() {
+ if (!enabled_) {
+ return;
+ }
+ enabled_ = false;
+ for (ProtocolHandlerMap::const_iterator p = protocol_handlers_.begin();
+ p != protocol_handlers_.end(); p++) {
+ delegate_->DeregisterExternalHandler(p->first);
+ }
+}
+
+ProtocolHandlerList ProtocolHandlerRegistry::GetHandlersFromPref(
+ const char* pref_name) {
+ ProtocolHandlerList result;
+ PrefService* prefs = profile_->GetPrefs();
+ if (!prefs->HasPrefPath(pref_name)) {
+ return result;
+ }
+
+ const ListValue* handlers = prefs->GetList(pref_name);
+ if (handlers) {
+ for (size_t i = 0; i < handlers->GetSize(); i++) {
+ DictionaryValue* dict;
+ handlers->GetDictionary(i, &dict);
+ ProtocolHandler* handler = ProtocolHandler::CreateProtocolHandler(dict);
+ if (handler) {
+ result.push_back(handler);
+ }
}
- net::URLRequest::RegisterProtocolFactory(handler->protocol(),
- &ProtocolHandlerRegistry::Factory);
}
- protocolHandlers_[handler->protocol()] = handler;
+ return result;
}
void ProtocolHandlerRegistry::Load() {
PrefService* prefs = profile_->GetPrefs();
- if (!prefs->HasPrefPath(prefs::kRegisteredProtocolHandlers)) {
- return;
+ if (prefs->HasPrefPath(prefs::kCustomHandlersEnabled)) {
+ enabled_ = prefs->GetBoolean(prefs::kCustomHandlersEnabled);
}
- const ListValue* protocolHandlers =
- prefs->GetList(prefs::kRegisteredProtocolHandlers);
-
- for (size_t i = 0; i < protocolHandlers->GetSize(); i++) {
- DictionaryValue* dict;
- protocolHandlers->GetDictionary(i, &dict);
- RegisterHandlerFromValue(dict);
+ ProtocolHandlerList registered_handlers =
+ GetHandlersFromPref(prefs::kRegisteredProtocolHandlers);
+ for (ProtocolHandlerList::iterator p = registered_handlers.begin();
+ p != registered_handlers.end(); p++) {
+ RegisterProtocolHandler(*p);
+ }
+ ProtocolHandlerList ignored_handlers =
+ GetHandlersFromPref(prefs::kIgnoredProtocolHandlers);
+ for (ProtocolHandlerList::iterator p = ignored_handlers.begin();
+ p != ignored_handlers.end(); p++) {
+ IgnoreProtocolHandler(*p);
}
}
@@ -57,36 +128,84 @@ void ProtocolHandlerRegistry::RegisterHandlerFromValue(
}
void ProtocolHandlerRegistry::Save() {
- scoped_ptr<Value> value(Encode());
- profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers, *value);
+ scoped_ptr<Value> registered_protocol_handlers(EncodeRegisteredHandlers());
+ scoped_ptr<Value> ignored_protocol_handlers(EncodeIgnoredHandlers());
+ scoped_ptr<Value> enabled(Value::CreateBooleanValue(enabled_));
+ profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers,
+ *registered_protocol_handlers);
+ profile_->GetPrefs()->Set(prefs::kIgnoredProtocolHandlers,
+ *ignored_protocol_handlers);
+ profile_->GetPrefs()->Set(prefs::kCustomHandlersEnabled, *enabled);
profile_->GetPrefs()->ScheduleSavePersistentPrefs();
}
ProtocolHandler* ProtocolHandlerRegistry::GetHandlerFor(
const std::string& scheme) const {
- ProtocolHandlerMap::const_iterator i = protocolHandlers_.find(scheme);
- return i == protocolHandlers_.end() ? NULL : i->second;
+ ProtocolHandlerMap::const_iterator i = protocol_handlers_.find(scheme);
+ return i == protocol_handlers_.end() ? NULL : i->second;
}
bool ProtocolHandlerRegistry::CanSchemeBeOverridden(
const std::string& scheme) const {
return GetHandlerFor(scheme) != NULL ||
- !net::URLRequest::IsHandledProtocol(scheme);
+ !delegate_->IsExternalHandlerRegistered(scheme);
+}
+
+void ProtocolHandlerRegistry::GetHandledProtocols(
+ std::vector<std::string>* output) {
+ ProtocolHandlerMap::iterator p;
+ for (p = protocol_handlers_.begin(); p != protocol_handlers_.end(); p++) {
+ output->push_back(p->first);
+ }
}
-bool ProtocolHandlerRegistry::IsAlreadyRegistered(
+void ProtocolHandlerRegistry::RemoveHandlerFor(const std::string& scheme) {
+ RemoveAndDelete(protocol_handlers_, scheme);
+ net::URLRequest::RegisterProtocolFactory(scheme, NULL);
+ Save();
+}
+
+void ProtocolHandlerRegistry::RemoveIgnoredHandler(ProtocolHandler* handler) {
+ for (ProtocolHandlerList::iterator p = ignored_protocol_handlers_.begin();
+ p != ignored_protocol_handlers_.end(); p++) {
+ if (*handler == **p) {
+ ProtocolHandler* removed_handler = *p;
+ ignored_protocol_handlers_.erase(p);
+ delete removed_handler;
+ break;
+ }
+ }
+}
+
+bool ProtocolHandlerRegistry::IsRegistered(
const ProtocolHandler* handler) const {
ProtocolHandler* currentHandler = GetHandlerFor(handler->protocol());
return currentHandler && *currentHandler == *handler;
}
+bool ProtocolHandlerRegistry::IsIgnored(const ProtocolHandler* handler) const {
+ ProtocolHandlerList::const_iterator i;
+ for (i = ignored_protocol_handlers_.begin();
+ i != ignored_protocol_handlers_.end(); i++) {
+ if (**i == *handler) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool ProtocolHandlerRegistry::IsHandledProtocol(
+ const std::string& scheme) const {
+ return GetHandlerFor(scheme);
+}
+
net::URLRequestJob* ProtocolHandlerRegistry::Factory(net::URLRequest* request,
const std::string& scheme) {
return request->context()->network_delegate()->MaybeCreateURLRequestJob(
request);
}
-
net::URLRequestJob* ProtocolHandlerRegistry::MaybeCreateJob(
net::URLRequest* request) const {
ProtocolHandler* handler = GetHandlerFor(request->url().scheme());
@@ -104,16 +223,24 @@ net::URLRequestJob* ProtocolHandlerRegistry::MaybeCreateJob(
return new net::URLRequestRedirectJob(request, translated_url);
}
-ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {}
+Value* ProtocolHandlerRegistry::EncodeRegisteredHandlers() {
+ ListValue* protocol_handlers = new ListValue();
-Value* ProtocolHandlerRegistry::Encode() {
- ListValue* protocolHandlers = new ListValue();
+ for (ProtocolHandlerMap::iterator i = protocol_handlers_.begin();
+ i != protocol_handlers_.end(); ++i) {
+ protocol_handlers->Append(i->second->Encode());
+ }
+ return protocol_handlers;
+}
- for (ProtocolHandlerMap::iterator i = protocolHandlers_.begin();
- i != protocolHandlers_.end(); ++i) {
- protocolHandlers->Append(i->second->Encode());
+Value* ProtocolHandlerRegistry::EncodeIgnoredHandlers() {
+ ListValue* handlers = new ListValue();
+
+ for (ProtocolHandlerList::iterator i = ignored_protocol_handlers_.begin();
+ i != ignored_protocol_handlers_.end(); ++i) {
+ handlers->Append((*i)->Encode());
}
- return protocolHandlers;
+ return handlers;
}
void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler(
@@ -126,6 +253,40 @@ void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler(
ProtocolHandler* handler) {
}
+void ProtocolHandlerRegistry::OnIgnoreRegisterProtocolHandler(
+ ProtocolHandler* handler) {
+ IgnoreProtocolHandler(handler);
+ Save();
+}
+
void ProtocolHandlerRegistry::RegisterPrefs(PrefService* prefService) {
prefService->RegisterListPref(prefs::kRegisteredProtocolHandlers);
+ prefService->RegisterListPref(prefs::kIgnoredProtocolHandlers);
+ prefService->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true);
+}
+
+// Delegate --------------------------------------------------------------------
+
+ProtocolHandlerRegistry::Delegate::~Delegate() {
+}
+
+void ProtocolHandlerRegistry::Delegate::RegisterExternalHandler(
+ const std::string& protocol) {
+ ChildProcessSecurityPolicy* policy =
+ ChildProcessSecurityPolicy::GetInstance();
+ if (!policy->IsWebSafeScheme(protocol)) {
+ policy->RegisterWebSafeScheme(protocol);
+ }
+ net::URLRequest::RegisterProtocolFactory(protocol,
+ &ProtocolHandlerRegistry::Factory);
+}
+
+void ProtocolHandlerRegistry::Delegate::DeregisterExternalHandler(
+ const std::string& protocol) {
+ net::URLRequest::RegisterProtocolFactory(protocol, NULL);
+}
+
+bool ProtocolHandlerRegistry::Delegate::IsExternalHandlerRegistered(
+ const std::string& protocol) {
+ return net::URLRequest::IsHandledProtocol(protocol);
}
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.h b/chrome/browser/custom_handlers/protocol_handler_registry.h
index 9ae3cfc..868bd2b 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.h
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.h
@@ -6,18 +6,21 @@
#define CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
#pragma once
-#include <string>
#include <map>
+#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/values.h"
-#include "chrome/browser/custom_handlers/protocol_handler.h"
#include "chrome/browser/profiles/profile.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
+class ProtocolHandler;
+typedef std::map<std::string, ProtocolHandler*> ProtocolHandlerMap;
+typedef std::vector<ProtocolHandler*> ProtocolHandlerList;
// This is where handlers for protocols registered with
// navigator.registerProtocolHandler() are registered. Each Profile owns an
@@ -28,7 +31,10 @@
class ProtocolHandlerRegistry
: public base::RefCountedThreadSafe<ProtocolHandlerRegistry> {
public:
- explicit ProtocolHandlerRegistry(Profile* profile);
+ class Delegate;
+
+ ProtocolHandlerRegistry(Profile* profile, Delegate* delegate);
+ ~ProtocolHandlerRegistry();
// Called when the user accepts the registration of a given protocol handler.
void OnAcceptRegisterProtocolHandler(ProtocolHandler* handler);
@@ -36,6 +42,10 @@ class ProtocolHandlerRegistry
// Called when the user denies the registration of a given protocol handler.
void OnDenyRegisterProtocolHandler(ProtocolHandler* handler);
+ // Called when the user indicates that they don't want to be asked about the
+ // given protocol handler again.
+ void OnIgnoreRegisterProtocolHandler(ProtocolHandler* handler);
+
// Loads a user's registered protocol handlers.
void Load();
@@ -45,12 +55,27 @@ class ProtocolHandlerRegistry
// Returns the handler for this protocol.
ProtocolHandler* GetHandlerFor(const std::string& scheme) const;
+ // Yields a list of the protocols handled by this registry.
+ void GetHandledProtocols(std::vector<std::string>* output);
+
// Returns true if we allow websites to register handlers for the given
// scheme.
bool CanSchemeBeOverridden(const std::string& scheme) const;
// Returns true if an identical protocol handler has already been registered.
- bool IsAlreadyRegistered(const ProtocolHandler* handler) const;
+ bool IsRegistered(const ProtocolHandler* handler) const;
+
+ // Returns true if the protocol handler is being ignored.
+ bool IsIgnored(const ProtocolHandler* handler) const;
+
+ // Returns true if the protocol has a registered protocol handler.
+ bool IsHandledProtocol(const std::string& scheme) const;
+
+ // Removes any existing protocol handler for the given protocol.
+ void RemoveHandlerFor(const std::string& scheme);
+
+ // Causes the given protocol handler to not be ignored anymore.
+ void RemoveIgnoredHandler(ProtocolHandler* handler);
// URLRequestFactory for use with URLRequest::RegisterProtocolFactory().
// Redirects any URLRequests for which there is a matching protocol handler.
@@ -64,28 +89,68 @@ class ProtocolHandlerRegistry
// 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();
+
+ // Puts this registry in the disabled state - registered protocol handlers
+ // will not handle requests.
+ void Disable();
+
+ bool enabled() { return enabled_; }
+
+ class Delegate {
+ public:
+ virtual ~Delegate();
+ virtual void RegisterExternalHandler(const std::string& protocol);
+ virtual void DeregisterExternalHandler(const std::string& protocol);
+ virtual bool IsExternalHandlerRegistered(const std::string& protocol);
+ };
+
private:
- typedef std::map<std::string, ProtocolHandler*> ProtocolHandlerMap;
friend class base::RefCountedThreadSafe<ProtocolHandlerRegistry>;
- ~ProtocolHandlerRegistry();
- // Returns a JSON dictionary of protocols to protocol handlers. The caller is
+ // Returns a JSON list of protocol handlers. The caller is responsible for
+ // deleting this Value.
+ Value* EncodeRegisteredHandlers();
+
+ // Returns a JSON list of ignored protocol handlers. The caller is
// responsible for deleting this Value.
- Value* Encode();
+ Value* EncodeIgnoredHandlers();
// Registers a new protocol handler.
void RegisterProtocolHandler(ProtocolHandler* handler);
+ // Get the ProtocolHandlers stored under the given pref name. The caller owns
+ // the returned ProtocolHandlers and is responsible for deleting them.
+ ProtocolHandlerList GetHandlersFromPref(const char* pref_name);
+
+ // Ignores future requests to register the given protocol handler.
+ void IgnoreProtocolHandler(ProtocolHandler* handler);
+
// Registers a new protocol handler from a JSON dictionary.
void RegisterHandlerFromValue(const DictionaryValue* value);
+ // Register
+ void IgnoreHandlerFromValue(const DictionaryValue* value);
+
// Map from protocols (strings) to protocol handlers.
- ProtocolHandlerMap protocolHandlers_;
+ ProtocolHandlerMap protocol_handlers_;
+
+ // Protocol handlers that the user has told us to ignore.
+ ProtocolHandlerList ignored_protocol_handlers_;
// The Profile that owns this ProtocolHandlerRegistry.
Profile* profile_;
+ // The Delegate that registers / deregisters external handlers on our behalf.
+ scoped_ptr<Delegate> delegate_;
+
+ // If false then registered protocol handlers will not be used to handle
+ // requests.
+ bool enabled_;
+
DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
};
#endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
new file mode 100644
index 0000000..9938837
--- /dev/null
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -0,0 +1,134 @@
+// Copyright (c) 2011 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.h"
+
+#include "base/scoped_ptr.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/custom_handlers/protocol_handler.h"
+#include "chrome/test/testing_browser_process.h"
+#include "chrome/test/testing_browser_process_test.h"
+#include "chrome/test/testing_browser_process_test.h"
+#include "chrome/test/testing_pref_service.h"
+#include "chrome/test/testing_profile.h"
+#include "content/common/notification_observer.h"
+#include "content/common/notification_registrar.h"
+#include "content/common/notification_service.h"
+
+class FakeDelegate : public ProtocolHandlerRegistry::Delegate {
+ public:
+ virtual ~FakeDelegate() { }
+ virtual void RegisterExternalHandler(const std::string& protocol) {
+ registered_protocols_.insert(protocol);
+ }
+ virtual void DeregisterExternalHandler(const std::string& protocol) {
+ registered_protocols_.erase(protocol);
+ }
+
+ bool IsExternalHandlerRegistered(const std::string& protocol) {
+ return registered_protocols_.find(protocol) != registered_protocols_.end();
+ }
+
+ void Reset() {
+ registered_protocols_.clear();
+ }
+
+ private:
+ std::set<std::string> registered_protocols_;
+};
+
+
+class ProtocolHandlerRegistryTest : public testing::Test {
+ public:
+ FakeDelegate* delegate() const { return delegate_; }
+ TestingProfile* profile() const { return profile_.get(); }
+ PrefService* pref_service() const { return profile_->GetPrefs(); }
+ ProtocolHandlerRegistry* registry() const { return registry_.get(); }
+
+ ProtocolHandler* CreateProtocolHandler(const std::string& protocol,
+ const GURL& url,
+ const std::string& title) {
+ return ProtocolHandler::CreateProtocolHandler(protocol, url,
+ UTF8ToUTF16(title));
+ }
+
+ ProtocolHandler* MakeProtocolHandler(const std::string& protocol) {
+ return CreateProtocolHandler(protocol, GURL("http://blah.com/%s"),
+ protocol);
+ }
+
+ ProtocolHandler* TestProtocolHandler() {
+ return CreateProtocolHandler("test", GURL("http://test.com/%s"), "Test");
+ }
+
+ void ReloadProtocolHandlerRegistry() {
+ delegate_ = new FakeDelegate(*delegate_); // Copy across the delegate.
+ registry_ = new ProtocolHandlerRegistry(profile(), delegate());
+ registry_->Load();
+ }
+
+ private:
+ virtual void SetUp() {
+ profile_.reset(new TestingProfile());
+ profile_->SetPrefService(new TestingPrefService());
+ delegate_ = new FakeDelegate();
+ registry_ = new ProtocolHandlerRegistry(profile(), delegate());
+ registry_->Load();
+
+ ProtocolHandlerRegistry::RegisterPrefs(pref_service());
+ }
+
+ FakeDelegate* delegate_;
+ scoped_ptr<TestingProfile> profile_;
+ scoped_refptr<ProtocolHandlerRegistry> registry_;
+};
+
+TEST_F(ProtocolHandlerRegistryTest, AcceptProtocolHandlerHandlesProtocol) {
+ ASSERT_FALSE(registry()->IsHandledProtocol("test"));
+ registry()->OnAcceptRegisterProtocolHandler(TestProtocolHandler());
+ ASSERT_TRUE(registry()->IsHandledProtocol("test"));
+}
+
+TEST_F(ProtocolHandlerRegistryTest, DisableDeregistersProtocolHandlers) {
+ ASSERT_FALSE(delegate()->IsExternalHandlerRegistered("test"));
+ registry()->OnAcceptRegisterProtocolHandler(TestProtocolHandler());
+ ASSERT_TRUE(delegate()->IsExternalHandlerRegistered("test"));
+
+ registry()->Disable();
+ ASSERT_FALSE(delegate()->IsExternalHandlerRegistered("test"));
+ registry()->Enable();
+ ASSERT_TRUE(delegate()->IsExternalHandlerRegistered("test"));
+}
+
+TEST_F(ProtocolHandlerRegistryTest, IgnoreProtocolHandler) {
+ registry()->OnIgnoreRegisterProtocolHandler(TestProtocolHandler());
+ ASSERT_TRUE(registry()->IsIgnored(TestProtocolHandler()));
+ registry()->RemoveIgnoredHandler(TestProtocolHandler());
+ ASSERT_FALSE(registry()->IsIgnored(TestProtocolHandler()));
+}
+
+TEST_F(ProtocolHandlerRegistryTest, SaveAndLoad) {
+ registry()->OnAcceptRegisterProtocolHandler(TestProtocolHandler());
+ registry()->OnIgnoreRegisterProtocolHandler(MakeProtocolHandler("stuff"));
+
+ ASSERT_TRUE(registry()->IsHandledProtocol("test"));
+ ASSERT_TRUE(registry()->IsIgnored(MakeProtocolHandler("stuff")));
+ delegate()->Reset();
+ ReloadProtocolHandlerRegistry();
+ ASSERT_TRUE(registry()->IsHandledProtocol("test"));
+ ASSERT_TRUE(registry()->IsIgnored(MakeProtocolHandler("stuff")));
+}
+
+TEST_F(ProtocolHandlerRegistryTest, TestEnabledDisabled) {
+ registry()->Disable();
+ ASSERT_FALSE(registry()->enabled());
+ registry()->Enable();
+ ASSERT_TRUE(registry()->enabled());
+}
+
+TEST_F(ProtocolHandlerRegistryTest,
+ DisallowRegisteringExternallyHandledProtocols) {
+ delegate()->RegisterExternalHandler("test");
+ ASSERT_FALSE(registry()->CanSchemeBeOverridden("test"));
+}
diff --git a/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc b/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc
index 3d12986..9bd9176 100644
--- a/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc
+++ b/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/custom_handlers/protocol_handler.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index af5049b..1b4625d 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -564,7 +564,8 @@ void ProfileImpl::InitPromoResources() {
void ProfileImpl::InitRegisteredProtocolHandlers() {
if (protocol_handler_registry_)
return;
- protocol_handler_registry_ = new ProtocolHandlerRegistry(this);
+ protocol_handler_registry_ = new ProtocolHandlerRegistry(this,
+ new ProtocolHandlerRegistry::Delegate());
protocol_handler_registry_->Load();
}
diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
index e723645..5da386f7 100644
--- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
+++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/autofill/autofill_manager.h"
#include "chrome/browser/automation/automation_tab_helper.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
+#include "chrome/browser/custom_handlers/protocol_handler.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
#include "chrome/browser/extensions/extension_tab_helper.h"
@@ -320,11 +321,14 @@ void TabContentsWrapper::OnRegisterProtocolHandler(const std::string& protocol,
const GURL& url,
const string16& title) {
ProtocolHandlerRegistry* registry = profile()->GetProtocolHandlerRegistry();
+ if (!registry->enabled()) {
+ return;
+ }
ProtocolHandler* handler =
ProtocolHandler::CreateProtocolHandler(protocol, url, title);
if ((handler != NULL) &&
registry->CanSchemeBeOverridden(handler->protocol())) {
- tab_contents()->AddInfoBar(registry->IsAlreadyRegistered(handler) ?
+ tab_contents()->AddInfoBar(registry->IsRegistered(handler) ?
static_cast<InfoBarDelegate*>(new SimpleAlertInfoBarDelegate(
tab_contents(), NULL, l10n_util::GetStringFUTF16(
IDS_REGISTER_PROTOCOL_HANDLER_ALREADY_REGISTERED,
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index c1d50a6..879161c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1300,6 +1300,7 @@
'browser/content_settings/stub_settings_observer.cc',
'browser/content_settings/stub_settings_observer.h',
'browser/cookies_tree_model_unittest.cc',
+ 'browser/custom_handlers/protocol_handler_registry_unittest.cc',
'browser/debugger/devtools_manager_unittest.cc',
'browser/debugger/devtools_remote_listen_socket_unittest.cc',
'browser/debugger/devtools_remote_listen_socket_unittest.h',
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 0dfb87d..28a432d 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1350,11 +1350,19 @@ const char kManagedPopupsBlockedForUrls[] =
// needs to acknowledge this page.
const char kKnownBackgroundPages[] = "background_pages.known";
-// Dictionary that maps URL schemes (protocols) to URL handlers.
-const char kRegisteredProtocolHandlers[] = "registered_protocol_handlers";
-
// Set to true if the user created a login item so we should not modify it when
// uninstalling background apps.
const char kUserCreatedLoginItem[] = "background_mode.user_created_login_item";
+// List of protocol handlers.
+const char kRegisteredProtocolHandlers[] =
+ "custom_handlers.registered_protocol_handlers";
+
+// List of protocol handlers the user has requested not to be asked about again.
+const char kIgnoredProtocolHandlers[] =
+ "custom_handlers.ignored_protocol_handlers";
+
+// Whether user-specified handlers for protocols and content types can be
+// specified.
+const char kCustomHandlersEnabled[] = "custom_handlers.enabled";
} // namespace prefs
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index e212cec..6bb50db 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -498,6 +498,8 @@ extern const char kGSSAPILibraryName[];
extern const char kKnownBackgroundPages[];
extern const char kRegisteredProtocolHandlers[];
+extern const char kIgnoredProtocolHandlers[];
+extern const char kCustomHandlersEnabled[];
extern const char kUserCreatedLoginItem[];
diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc
index 03caad3..06c08d6 100644
--- a/chrome/test/testing_profile.cc
+++ b/chrome/test/testing_profile.cc
@@ -298,7 +298,8 @@ void TestingProfile::CreateAutocompleteClassifier() {
}
void TestingProfile::CreateProtocolHandlerRegistry() {
- protocol_handler_registry_ = new ProtocolHandlerRegistry(this);
+ protocol_handler_registry_ = new ProtocolHandlerRegistry(this,
+ new ProtocolHandlerRegistry::Delegate());
}
void TestingProfile::CreateWebDataService(bool delete_file) {