protocol_handler_registry.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/custom_handlers/protocol_handler_registry.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_io_data.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/custom_handlers/protocol_handler.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_prefs/user_prefs.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/child_process_security_policy.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_delegate.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_redirect_job.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ChildProcessSecurityPolicy; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProtocolHandler& LookupHandler( 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p = 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_map.find(scheme); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p != handler_map.end()) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p->second; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProtocolHandler::EmptyProtocolHandler(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If true default protocol handlers will be removed if the OS level 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// registration for a protocol is no longer Chrome. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldRemoveHandlersNotInOS() { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't do this on Linux as the OS registration there is not reliable, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and Chrome OS doesn't have any notion of OS registration. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(benwells): When Linux support is more reliable remove this 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // difference (http://crbug.com/88255). 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ShellIntegration::CanSetAsDefaultProtocolClient() != 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShellIntegration::SET_DEFAULT_NOT_ALLOWED; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// IOThreadDelegate ------------------------------------------------------------ 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// IOThreadDelegate is an IO thread specific object. Access to the class should 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// all be done via the IO thread. The registry living on the UI thread makes 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a best effort to update the IO object after local updates are completed. 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ProtocolHandlerRegistry::IOThreadDelegate 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public base::RefCountedThreadSafe< 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProtocolHandlerRegistry::IOThreadDelegate> { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a new instance. If |enabled| is true the registry is considered 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enabled on the IO thread. 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit IOThreadDelegate(bool enabled); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the protocol has a default protocol handler. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should be called only from the IO thread. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsHandledProtocol(const std::string& scheme) const; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clears the default for the provided protocol. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should be called only from the IO thread. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ClearDefault(const std::string& scheme); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Makes this ProtocolHandler the default handler for its protocol. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should be called only from the IO thread. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetDefault(const ProtocolHandler& handler); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a URL request job for the given request if there is a matching 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // protocol handler, returns NULL otherwise. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestJob* MaybeCreateJob( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, net::NetworkDelegate* network_delegate) const; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicate that the registry has been enabled in the IO thread's 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // copy of the data. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Enable() { enabled_ = true; } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicate that the registry has been disabled in the IO thread's copy of 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the data. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Disable() { enabled_ = false; } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCountedThreadSafe<IOThreadDelegate>; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~IOThreadDelegate(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy of protocol handlers use only on the IO thread. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerRegistry::ProtocolHandlerMap default_handlers_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Is the registry enabled on the IO thread. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enabled_; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IOThreadDelegate); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProtocolHandlerRegistry::IOThreadDelegate::IOThreadDelegate(bool) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : enabled_(true) {} 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProtocolHandlerRegistry::IOThreadDelegate::~IOThreadDelegate() {} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProtocolHandlerRegistry::IOThreadDelegate::IsHandledProtocol( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) const { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return enabled_ && !LookupHandler(default_handlers_, scheme).IsEmpty(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProtocolHandlerRegistry::IOThreadDelegate::ClearDefault( 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& scheme) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_handlers_.erase(scheme); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProtocolHandlerRegistry::IOThreadDelegate::SetDefault( 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ProtocolHandler& handler) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearDefault(handler.protocol()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_handlers_.insert(std::make_pair(handler.protocol(), handler)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Create a new job for the supplied |URLRequest| if a default handler 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is registered and the associated handler is able to interpret 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the url from |request|. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)net::URLRequestJob* ProtocolHandlerRegistry::IOThreadDelegate::MaybeCreateJob( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, net::NetworkDelegate* network_delegate) const { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandler handler = LookupHandler(default_handlers_, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->url().scheme()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler.IsEmpty()) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL translated_url(handler.TranslateUrl(request->url())); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!translated_url.is_valid()) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new net::URLRequestRedirectJob( 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request, network_delegate, translated_url, 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "Protocol Handler Registry"); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// JobInterceptorFactory ------------------------------------------------------- 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Instances of JobInterceptorFactory are produced for ownership by the IO 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread where it handler URL requests. We should never hold 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// any pointers on this class, only produce them in response to 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// requests via |ProtocolHandlerRegistry::CreateJobInterceptorFactory|. 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProtocolHandlerRegistry::JobInterceptorFactory::JobInterceptorFactory( 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IOThreadDelegate* io_thread_delegate) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : io_thread_delegate_(io_thread_delegate) { 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(io_thread_delegate_.get()); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DetachFromThread(); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProtocolHandlerRegistry::JobInterceptorFactory::~JobInterceptorFactory() { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProtocolHandlerRegistry::JobInterceptorFactory::Chain( 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<net::URLRequestJobFactory> job_factory) { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job_factory_ = job_factory.Pass(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)net::URLRequestJob* 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProtocolHandlerRegistry::JobInterceptorFactory:: 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MaybeCreateJobWithProtocolHandler( 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& scheme, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequest* request, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetworkDelegate* network_delegate) const { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestJob* job = io_thread_delegate_->MaybeCreateJob( 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request, network_delegate); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (job) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return job; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return job_factory_->MaybeCreateJobWithProtocolHandler( 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheme, request, network_delegate); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProtocolHandlerRegistry::JobInterceptorFactory::IsHandledProtocol( 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& scheme) const { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return io_thread_delegate_->IsHandledProtocol(scheme) || 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job_factory_->IsHandledProtocol(scheme); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProtocolHandlerRegistry::JobInterceptorFactory::IsHandledURL( 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url) const { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (url.is_valid() && 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_thread_delegate_->IsHandledProtocol(url.scheme())) || 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job_factory_->IsHandledURL(url); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool ProtocolHandlerRegistry::JobInterceptorFactory::IsSafeRedirectTarget( 209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const GURL& location) const { 210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return job_factory_->IsSafeRedirectTarget(location); 212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DefaultClientObserver ------------------------------------------------------ 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::DefaultClientObserver::DefaultClientObserver( 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerRegistry* registry) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : worker_(NULL), 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registry_(registry) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(registry_); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::DefaultClientObserver::~DefaultClientObserver() { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (worker_) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->ObserverDestroyed(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultClientObserverList::iterator iter = std::find( 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registry_->default_client_observers_.begin(), 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registry_->default_client_observers_.end(), this); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registry_->default_client_observers_.erase(iter); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState( 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShellIntegration::DefaultWebClientUIState state) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (worker_) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldRemoveHandlersNotInOS() && 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (state == ShellIntegration::STATE_NOT_DEFAULT)) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registry_->ClearDefault(worker_->protocol()); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::DefaultClientObserver:: 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsInteractiveSetDefaultPermitted() { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::DefaultClientObserver::SetWorker( 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShellIntegration::DefaultProtocolClientWorker* worker) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_ = worker; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::DefaultClientObserver::IsOwnedByWorker() { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delegate -------------------------------------------------------------------- 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::Delegate::~Delegate() {} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::Delegate::RegisterExternalHandler( 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& protocol) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChildProcessSecurityPolicy* policy = 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChildProcessSecurityPolicy::GetInstance(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!policy->IsWebSafeScheme(protocol)) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy->RegisterWebSafeScheme(protocol); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::Delegate::DeregisterExternalHandler( 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& protocol) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::Delegate::IsExternalHandlerRegistered( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& protocol) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE(koz): This function is safe to call from any thread, despite living 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in ProfileIOData. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProfileIOData::IsHandledProtocol(protocol); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ShellIntegration::DefaultProtocolClientWorker* 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::Delegate::CreateShellWorker( 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShellIntegration::DefaultWebClientObserver* observer, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& protocol) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ShellIntegration::DefaultProtocolClientWorker(observer, protocol); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::DefaultClientObserver* 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::Delegate::CreateShellObserver( 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerRegistry* registry) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new DefaultClientObserver(registry); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::Delegate::RegisterWithOSAsDefaultClient( 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& protocol, ProtocolHandlerRegistry* registry) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultClientObserver* observer = CreateShellObserver(registry); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The worker pointer is reference counted. While it is running the 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message loops of the FILE and UI thread will hold references to it 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and it will be automatically freed once all its tasks have finished. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ShellIntegration::DefaultProtocolClientWorker> worker; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = CreateShellWorker(observer, protocol); 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) observer->SetWorker(worker.get()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registry->default_client_observers_.push_back(observer); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker->StartSetAsDefault(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProtocolHandlerRegistry ----------------------------------------------------- 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ProtocolHandlerRegistry::ProtocolHandlerRegistry( 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserContext* context, Delegate* delegate) 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : context_(context), 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_(delegate), 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enabled_(true), 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_loading_(false), 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_loaded_(false), 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_thread_delegate_(new IOThreadDelegate(enabled_)){ 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest( 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler.IsEmpty() || !CanSchemeBeOverridden(handler.protocol())) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!enabled() || IsRegistered(handler) || HasIgnoredEquivalent(handler)) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (AttemptReplace(handler)) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler( 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RegisterProtocolHandler(handler, USER); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetDefault(handler); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Save(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler( 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RegisterProtocolHandler(handler, USER); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Save(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::OnIgnoreRegisterProtocolHandler( 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IgnoreProtocolHandler(handler, USER); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Save(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::AttemptReplace(const ProtocolHandler& handler) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandler old_default = GetHandlerFor(handler.protocol()); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool make_new_handler_default = handler.IsSameOrigin(old_default); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList to_replace(GetReplacedHandlers(handler)); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_replace.empty()) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ProtocolHandlerList::iterator p = to_replace.begin(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p != to_replace.end(); ++p) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveHandler(*p); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (make_new_handler_default) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnAcceptRegisterProtocolHandler(handler); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertHandler(handler); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::ProtocolHandlerList 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::GetReplacedHandlers( 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) const { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList replaced_handlers; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandlerList* handlers = GetHandlerList(handler.protocol()); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handlers) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return replaced_handlers; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ProtocolHandlerList::const_iterator p = handlers->begin(); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p != handlers->end(); p++) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler.IsSameOrigin(*p)) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replaced_handlers.push_back(*p); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return replaced_handlers; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_handlers_.erase(scheme); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IOThreadDelegate::ClearDefault, io_thread_delegate_, scheme)); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Save(); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::IsDefault( 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) const { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetHandlerFor(handler.protocol()) == handler; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::InstallDefaultsForChromeOS() { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only chromeos has default protocol handlers at this point. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddPredefinedHandler( 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandler::CreateProtocolHandler( 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mailto", 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_MAILTO_HANDLER_URL)))); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddPredefinedHandler( 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandler::CreateProtocolHandler( 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "webcal", 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL(l10n_util::GetStringUTF8(IDS_GOOGLE_WEBCAL_HANDLER_URL)))); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); // this method should only ever be called in chromeos. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::InitProtocolSettings() { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Any further default additions to the table will get rejected from now on. 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_loaded_ = true; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_loading_ = true; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PrefService* prefs = user_prefs::UserPrefs::Get(context_); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs->HasPrefPath(prefs::kCustomHandlersEnabled)) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs->GetBoolean(prefs::kCustomHandlersEnabled)) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Enable(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Disable(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RegisterProtocolHandlersFromPref(prefs::kPolicyRegisteredProtocolHandlers, 44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) POLICY); 44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RegisterProtocolHandlersFromPref(prefs::kRegisteredProtocolHandlers, USER); 44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IgnoreProtocolHandlersFromPref(prefs::kPolicyIgnoredProtocolHandlers, POLICY); 45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IgnoreProtocolHandlersFromPref(prefs::kIgnoredProtocolHandlers, USER); 45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_loading_ = false; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For each default protocol handler, check that we are still registered 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the OS as the default application. 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldRemoveHandlersNotInOS()) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ProtocolHandlerMap::const_iterator p = default_handlers_.begin(); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p != default_handlers_.end(); ++p) { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandler handler = p->second; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultClientObserver* observer = delegate_->CreateShellObserver(this); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ShellIntegration::DefaultProtocolClientWorker> worker; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = delegate_->CreateShellWorker(observer, handler.protocol()); 463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) observer->SetWorker(worker.get()); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_client_observers_.push_back(observer); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker->StartCheckIsDefault(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProtocolHandlerRegistry::GetHandlerIndex(const std::string& scheme) const { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler = GetHandlerFor(scheme); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler.IsEmpty()) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandlerList* handlers = GetHandlerList(scheme); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handlers) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList::const_iterator p; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, p = handlers->begin(); p != handlers->end(); ++p, ++i) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*p == handler) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::ProtocolHandlerList 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::GetHandlersFor( 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) const { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.find(scheme); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p == protocol_handlers_.end()) { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProtocolHandlerList(); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p->second; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::ProtocolHandlerList 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::GetIgnoredHandlers() { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ignored_protocol_handlers_; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::GetRegisteredProtocols( 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* output) const { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMultiMap::const_iterator p; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (p = protocol_handlers_.begin(); p != protocol_handlers_.end(); ++p) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!p->second.empty()) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->push_back(p->first); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::CanSchemeBeOverridden( 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) const { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandlerList* handlers = GetHandlerList(scheme); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we already have a handler for this scheme, we can add more. 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handlers != NULL && !handlers->empty()) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't override a scheme if it already has an external handler. 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !delegate_->IsExternalHandlerRegistered(scheme); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::IsRegistered( 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) const { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandlerList* handlers = GetHandlerList(handler.protocol()); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handlers) { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::find(handlers->begin(), handlers->end(), handler) != 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handlers->end(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::IsIgnored(const ProtocolHandler& handler) const { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList::const_iterator i; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = ignored_protocol_handlers_.begin(); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != ignored_protocol_handlers_.end(); ++i) { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*i == handler) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::HasRegisteredEquivalent( 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) const { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandlerList* handlers = GetHandlerList(handler.protocol()); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handlers) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList::const_iterator i; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = handlers->begin(); i != handlers->end(); ++i) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler.IsEquivalent(*i)) { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::HasIgnoredEquivalent( 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) const { 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList::const_iterator i; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = ignored_protocol_handlers_.begin(); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != ignored_protocol_handlers_.end(); ++i) { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler.IsEquivalent(*i)) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::RemoveIgnoredHandler( 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) { 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool should_notify = false; 58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (HandlerExists(handler, ignored_protocol_handlers_) && 58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) HandlerExists(handler, user_ignored_protocol_handlers_)) { 58346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EraseHandler(handler, &user_ignored_protocol_handlers_); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Save(); 58546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!HandlerExists(handler, policy_ignored_protocol_handlers_)) { 58646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EraseHandler(handler, &ignored_protocol_handlers_); 58746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) should_notify = true; 58846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_notify) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProtocolHandlerRegistry::IsHandledProtocol( 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) const { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return enabled_ && !GetHandlerFor(scheme).IsEmpty(); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::RemoveHandler( 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList& handlers = protocol_handlers_[handler.protocol()]; 60446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool erase_success = false; 60546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (HandlerExists(handler, handlers) && 60646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) HandlerExists(handler, &user_protocol_handlers_)) { 60746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EraseHandler(handler, &user_protocol_handlers_); 60846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!HandlerExists(handler, &policy_protocol_handlers_)) { 60946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) erase_success = true; 61046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EraseHandler(handler, &protocol_handlers_); 61146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMap::iterator q = default_handlers_.find(handler.protocol()); 61446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (erase_success && q != default_handlers_.end() && q->second == handler) { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make the new top handler in the list the default. 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handlers.empty()) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE We pass a copy because SetDefault() modifies handlers. 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetDefault(ProtocolHandler(handlers[0])); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IOThreadDelegate::ClearDefault, io_thread_delegate_, 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) q->second.protocol())); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_handlers_.erase(q); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 62946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (erase_success && !IsHandledProtocol(handler.protocol())) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DeregisterExternalHandler(handler.protocol()); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Save(); 63346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (erase_success) 63446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NotifyChanged(); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::RemoveDefaultHandler(const std::string& scheme) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandler current_default = GetHandlerFor(scheme); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!current_default.IsEmpty()) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveHandler(current_default); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProtocolHandler& ProtocolHandlerRegistry::GetHandlerFor( 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) const { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LookupHandler(default_handlers_, scheme); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::Enable() { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enabled_) { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enabled_ = true; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IOThreadDelegate::Enable, io_thread_delegate_)); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMap::const_iterator p; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->RegisterExternalHandler(p->first); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Save(); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::Disable() { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!enabled_) { 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enabled_ = false; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IOThreadDelegate::Disable, io_thread_delegate_)); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMap::const_iterator p; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->DeregisterExternalHandler(p->first); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Save(); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::Shutdown() { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_.reset(NULL); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We free these now in case there are any outstanding workers running. If 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we didn't free them they could respond to workers and try to update the 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // protocol handler registry after it was deleted. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Observers remove themselves from this list when they are deleted; so 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we delete the last item until none are left in the list. 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!default_client_observers_.empty()) { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete default_client_observers_.back(); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ProtocolHandlerRegistry::RegisterProfilePrefs( 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable* registry) { 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterListPref(prefs::kRegisteredProtocolHandlers, 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterListPref(prefs::kIgnoredProtocolHandlers, 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 70846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) registry->RegisterListPref(prefs::kPolicyRegisteredProtocolHandlers, 70946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 71046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) registry->RegisterListPref(prefs::kPolicyIgnoredProtocolHandlers, 71146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registry->RegisterBooleanPref( 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) prefs::kCustomHandlersEnabled, 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true, 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::~ProtocolHandlerRegistry() { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(default_client_observers_.empty()); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsRegistered(handler)); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMultiMap::iterator p = 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handlers_.find(handler.protocol()); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList& list = p->second; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list.erase(std::find(list.begin(), list.end(), handler)); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list.insert(list.begin(), handler); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::Save() { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_loading_) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> registered_protocol_handlers( 7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EncodeRegisteredHandlers()); 7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> ignored_protocol_handlers(EncodeIgnoredHandlers()); 7415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PrefService* prefs = user_prefs::UserPrefs::Get(context_); 7425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefs->Set(prefs::kRegisteredProtocolHandlers, 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *registered_protocol_handlers); 7455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefs->Set(prefs::kIgnoredProtocolHandlers, 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ignored_protocol_handlers); 7475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefs->SetBoolean(prefs::kCustomHandlersEnabled, enabled_); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProtocolHandlerRegistry::ProtocolHandlerList* 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::GetHandlerList( 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& scheme) const { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.find(scheme); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p == protocol_handlers_.end()) { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &p->second; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::SetDefault(const ProtocolHandler& handler) { 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMap::const_iterator p = default_handlers_.find( 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler.protocol()); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're not loading, and we are setting a default for a new protocol, 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // register with the OS. 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_loading_ && p == default_handlers_.end()) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->RegisterWithOSAsDefaultClient(handler.protocol(), this); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_handlers_.erase(handler.protocol()); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_handlers_.insert(std::make_pair(handler.protocol(), handler)); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PromoteHandler(handler); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IOThreadDelegate::SetDefault, io_thread_delegate_, handler)); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerMultiMap::iterator p = 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handlers_.find(handler.protocol()); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p != protocol_handlers_.end()) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->second.push_back(handler); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProtocolHandlerList new_list; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_list.push_back(handler); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handlers_[handler.protocol()] = new_list; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Value* ProtocolHandlerRegistry::EncodeRegisteredHandlers() { 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* protocol_handlers = new base::ListValue(); 79646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (ProtocolHandlerMultiMap::iterator i = user_protocol_handlers_.begin(); 79746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) i != user_protocol_handlers_.end(); 79846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++i) { 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ProtocolHandlerList::iterator j = i->second.begin(); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j != i->second.end(); ++j) { 8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* encoded = j->Encode(); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsDefault(*j)) { 803116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch encoded->Set("default", new base::FundamentalValue(true)); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handlers->Append(encoded); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return protocol_handlers; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Value* ProtocolHandlerRegistry::EncodeIgnoredHandlers() { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* handlers = new base::ListValue(); 81446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (ProtocolHandlerList::iterator i = 81546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) user_ignored_protocol_handlers_.begin(); 81646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) i != user_ignored_protocol_handlers_.end(); 81746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++i) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handlers->Append(i->Encode()); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handlers; 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::NotifyChanged() { 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED, 8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::Source<content::BrowserContext>(context_), 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::RegisterProtocolHandler( 83246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ProtocolHandler& handler, 83346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const HandlerSource source) { 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CanSchemeBeOverridden(handler.protocol())); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!handler.IsEmpty()); 83746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ProtocolHandlerMultiMap& map = 83846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (source == POLICY) ? policy_protocol_handlers_ : user_protocol_handlers_; 83946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ProtocolHandlerList& list = map[handler.protocol()]; 84046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!HandlerExists(handler, list)) 84146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) list.push_back(handler); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsRegistered(handler)) { 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enabled_ && !delegate_->IsExternalHandlerRegistered(handler.protocol())) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->RegisterExternalHandler(handler.protocol()); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertHandler(handler); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::vector<const base::DictionaryValue*> 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProtocolHandlerRegistry::GetHandlersFromPref(const char* pref_name) const { 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<const base::DictionaryValue*> result; 8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PrefService* prefs = user_prefs::UserPrefs::Get(context_); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs->HasPrefPath(pref_name)) { 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::ListValue* handlers = prefs->GetList(pref_name); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handlers) { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < handlers->GetSize(); ++i) { 8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* dict; 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handlers->GetDictionary(i, &dict)) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ProtocolHandler::IsValidDict(dict)) { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.push_back(dict); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 87346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProtocolHandlerRegistry::RegisterProtocolHandlersFromPref( 87446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const char* pref_name, 87546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const HandlerSource source) { 87646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::vector<const base::DictionaryValue*> registered_handlers = 87746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetHandlersFromPref(pref_name); 87846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (std::vector<const base::DictionaryValue*>::const_iterator p = 87946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) registered_handlers.begin(); 88046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) p != registered_handlers.end(); 88146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++p) { 88246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ProtocolHandler handler = ProtocolHandler::CreateProtocolHandler(*p); 88346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RegisterProtocolHandler(handler, source); 88446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool is_default = false; 88546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if ((*p)->GetBoolean("default", &is_default) && is_default) { 88646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SetDefault(handler); 88746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 88846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 88946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 89046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::IgnoreProtocolHandler( 89246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ProtocolHandler& handler, 89346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const HandlerSource source) { 89446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 89546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ProtocolHandlerList& list = (source == POLICY) 89646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ? policy_ignored_protocol_handlers_ 89746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : user_ignored_protocol_handlers_; 89846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!HandlerExists(handler, list)) 89946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) list.push_back(handler); 90046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (HandlerExists(handler, ignored_protocol_handlers_)) 90146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignored_protocol_handlers_.push_back(handler); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 90546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProtocolHandlerRegistry::IgnoreProtocolHandlersFromPref( 90646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const char* pref_name, 90746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const HandlerSource source) { 90846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::vector<const base::DictionaryValue*> ignored_handlers = 90946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetHandlersFromPref(pref_name); 91046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (std::vector<const base::DictionaryValue*>::const_iterator p = 91146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ignored_handlers.begin(); 91246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) p != ignored_handlers.end(); 91346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ++p) { 91446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IgnoreProtocolHandler(ProtocolHandler::CreateProtocolHandler(*p), source); 91546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 91646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 91746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 91846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool ProtocolHandlerRegistry::HandlerExists(const ProtocolHandler& handler, 91946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ProtocolHandlerMultiMap* map) { 92046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return HandlerExists(handler, (*map)[handler.protocol()]); 92146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 92246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 92346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool ProtocolHandlerRegistry::HandlerExists(const ProtocolHandler& handler, 92446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ProtocolHandlerList& list) { 92546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return std::find(list.begin(), list.end(), handler) != list.end(); 92646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 92746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 92846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProtocolHandlerRegistry::EraseHandler(const ProtocolHandler& handler, 92946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ProtocolHandlerMultiMap* map) { 93046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EraseHandler(handler, &(*map)[handler.protocol()]); 93146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 93246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 93346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProtocolHandlerRegistry::EraseHandler(const ProtocolHandler& handler, 93446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ProtocolHandlerList* list) { 93546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) list->erase(std::find(list->begin(), list->end(), handler)); 93646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 93746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProtocolHandlerRegistry::AddPredefinedHandler( 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProtocolHandler& handler) { 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_loaded_); // Must be called prior InitProtocolSettings. 94146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RegisterProtocolHandler(handler, USER); 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetDefault(handler); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProtocolHandlerRegistry::CreateJobInterceptorFactory() { 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this is always created on the UI thread (in profile_io's 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InitializeOnUIThread. Any method calls must be done 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the IO thread (this is checked). 951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return scoped_ptr<JobInterceptorFactory>( 952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new JobInterceptorFactory(io_thread_delegate_.get())); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 954