summaryrefslogtreecommitdiffstats
path: root/chrome/browser/custom_handlers/protocol_handler_registry.cc
diff options
context:
space:
mode:
authorhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-20 03:47:09 +0000
committerhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-20 03:47:09 +0000
commit92f18bfa18dc47a7b142e48235027d9d246801b7 (patch)
tree62252c0da5c0240d65d1dfabf017e3b405ccfe1b /chrome/browser/custom_handlers/protocol_handler_registry.cc
parent9224e78e827d79ded7fd7a30da53c7639dea10c0 (diff)
downloadchromium_src-92f18bfa18dc47a7b142e48235027d9d246801b7.zip
chromium_src-92f18bfa18dc47a7b142e48235027d9d246801b7.tar.gz
chromium_src-92f18bfa18dc47a7b142e48235027d9d246801b7.tar.bz2
A Speculative Revert for r147597 - 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 Review URL: https://chromiumcodereview.appspot.com/10546083 TBR=smckay@chromium.org Review URL: https://chromiumcodereview.appspot.com/10815026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147612 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/custom_handlers/protocol_handler_registry.cc')
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry.cc273
1 files changed, 64 insertions, 209 deletions
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index 712f791..5a6dfae 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -9,7 +9,6 @@
#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"
@@ -22,30 +21,14 @@
#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() {
@@ -61,165 +44,17 @@ bool ShouldRemoveHandlersNotInOS() {
#endif
}
-void InstallDefaultProtocolHandlers(ProtocolHandlerRegistry* registry) {
- // Only chromeos has default protocol handlers at this point.
- #if defined(OS_CHROMEOS)
- registry->AddPredefinedHandler(
- ProtocolHandler::CreateProtocolHandler(
- "mailto",
- GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_MAILTO_HANDLER_URL)),
- l10n_util::GetStringUTF16(IDS_GOOGLE_MAILTO_HANDLER_NAME)));
- registry->AddPredefinedHandler(
- ProtocolHandler::CreateProtocolHandler(
- "webcal",
- GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_WEBCAL_HANDLER_URL)),
- l10n_util::GetStringUTF16(IDS_GOOGLE_WEBCAL_HANDLER_NAME)));
- #endif
-}
-
-} // namespace
-
-// 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;
- }
+} // namespace
- virtual net::URLRequestJob* MaybeInterceptResponse(
- net::URLRequest* request) const OVERRIDE {
- return NULL;
+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;
}
-
- 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);
+ return ProtocolHandler::EmptyProtocolHandler();
}
// DefaultClientObserver ------------------------------------------------------
@@ -241,7 +76,8 @@ ProtocolHandlerRegistry::DefaultClientObserver::~DefaultClientObserver() {
registry_->default_client_observers_.erase(iter);
}
-void ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState(
+void
+ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState(
ShellIntegration::DefaultWebClientUIState state) {
if (worker_) {
if (ShouldRemoveHandlersNotInOS() &&
@@ -315,9 +151,9 @@ ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile,
: profile_(profile),
delegate_(delegate),
enabled_(true),
+ enabled_io_(enabled_),
is_loading_(false),
- is_loaded_(false),
- core_(new Core(enabled_)){
+ is_loaded_(false) {
}
bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest(
@@ -397,12 +233,11 @@ 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(&Core::ClearDefault, core_, scheme));
+ base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, scheme));
Save();
NotifyChanged();
}
@@ -413,23 +248,19 @@ bool ProtocolHandlerRegistry::IsDefault(
return GetHandlerFor(handler.protocol()) == handler;
}
-void ProtocolHandlerRegistry::InitProtocolSettings() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // Default protocol handlers must be installed first.
- InstallDefaultProtocolHandlers(this);
-
+void ProtocolHandlerRegistry::Load() {
// 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)) {
- if (prefs->GetBoolean(prefs::kCustomHandlersEnabled)) {
- Enable();
- } else {
- Disable();
- }
+ enabled_ = prefs->GetBoolean(prefs::kCustomHandlersEnabled);
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(enabled_ ? &ProtocolHandlerRegistry::EnableIO :
+ &ProtocolHandlerRegistry::DisableIO, this));
}
std::vector<const DictionaryValue*> registered_handlers =
GetHandlersFromPref(prefs::kRegisteredProtocolHandlers);
@@ -597,6 +428,12 @@ 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));
@@ -615,8 +452,8 @@ void ProtocolHandlerRegistry::RemoveHandler(
} else {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&Core::ClearDefault, core_, q->second.protocol()));
-
+ base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this,
+ q->second.protocol()));
default_handlers_.erase(q);
}
}
@@ -641,6 +478,21 @@ 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_) {
@@ -650,8 +502,7 @@ void ProtocolHandlerRegistry::Enable() {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(&Core::Enable, core_));
-
+ base::Bind(&ProtocolHandlerRegistry::EnableIO, this));
ProtocolHandlerMap::const_iterator p;
for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) {
delegate_->RegisterExternalHandler(p->first);
@@ -669,8 +520,7 @@ void ProtocolHandlerRegistry::Disable() {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(&Core::Disable, core_));
-
+ base::Bind(&ProtocolHandlerRegistry::DisableIO, this));
ProtocolHandlerMap::const_iterator p;
for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) {
delegate_->DeregisterExternalHandler(p->first);
@@ -679,7 +529,7 @@ void ProtocolHandlerRegistry::Disable() {
NotifyChanged();
}
-void ProtocolHandlerRegistry::Shutdown() {
+void ProtocolHandlerRegistry::Finalize() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
delegate_.reset(NULL);
// We free these now in case there are any outstanding workers running. If
@@ -703,7 +553,7 @@ void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) {
}
ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(default_client_observers_.empty());
}
@@ -717,6 +567,17 @@ 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_) {
@@ -757,7 +618,7 @@ void ProtocolHandlerRegistry::SetDefault(const ProtocolHandler& handler) {
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(&Core::SetDefault, core_, handler));
+ base::Bind(&ProtocolHandlerRegistry::SetDefaultIO, this, handler));
}
void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) {
@@ -854,16 +715,10 @@ void ProtocolHandlerRegistry::IgnoreProtocolHandler(
void ProtocolHandlerRegistry::AddPredefinedHandler(
const ProtocolHandler& handler) {
- DCHECK(!is_loaded_); // Must be called prior InitProtocolSettings.
+ // If called after the load command was issued this function will fail.
+ DCHECK(!is_loaded_);
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_);
-}
+