Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

RefCounted types should not have public destructors, chrome/browser/ …

…part 6

BUG=123295
TEST=none


Review URL: http://codereview.chromium.org/10071036

git-svn-id: http://src.chromium.org/svn/trunk/src/chrome/browser@134218 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
  • Loading branch information...
commit c5b08d9b01a753ddee4c29f80ca5cd867288edaa 1 parent 5574ef6
authored April 27, 2012

Showing 50 changed files with 730 additions and 610 deletions. Show diff stats Hide diff stats

  1. 4  autocomplete/builtin_provider.cc
  2. 5  autocomplete/builtin_provider.h
  3. 2  autocomplete/history_provider.cc
  4. 1  autocomplete/history_provider.h
  5. 4  autocomplete/history_quick_provider.cc
  6. 4  autocomplete/history_quick_provider.h
  7. 10  autocomplete/shortcuts_provider.cc
  8. 3  autocomplete/shortcuts_provider.h
  9. 3  autocomplete_history_manager_unittest.cc
  10. 4  autofill/autofill_external_delegate_unittest.cc
  11. 5  background/background_contents_service.cc
  12. 8  chrome_quota_permission_context.cc
  13. 4  chrome_quota_permission_context.h
  14. 5  content_settings/cookie_settings.cc
  15. 4  content_settings/cookie_settings.h
  16. 819  custom_handlers/protocol_handler_registry.cc
  17. 18  custom_handlers/protocol_handler_registry.h
  18. 2  custom_handlers/protocol_handler_registry_unittest.cc
  19. 7  debugger/devtools_sanity_unittest.cc
  20. 3  download/download_browsertest.cc
  21. 94  download/download_extension_api.h
  22. 4  external_protocol/external_protocol_handler_unittest.cc
  23. 15  geolocation/chrome_access_token_store.cc
  24. 5  geolocation/chrome_access_token_store.h
  25. 125  importer/external_process_importer_client.cc
  26. 4  importer/external_process_importer_client.h
  27. 2  importer/external_process_importer_host.cc
  28. 5  importer/external_process_importer_host.h
  29. 4  importer/firefox_importer_unittest_utils_mac.cc
  30. 5  intranet_redirect_detector.h
  31. 3  io_thread.cc
  32. 6  memory_purger.cc
  33. 26  metrics/field_trial_synchronizer.cc
  34. 11  metrics/field_trial_synchronizer.h
  35. 5  notifications/notification_test_util.cc
  36. 5  notifications/notification_test_util.h
  37. 7  pepper_gtalk_message_filter.cc
  38. 3  pepper_gtalk_message_filter.h
  39. 4  prerender/prerender_browsertest.cc
  40. 4  renderer_host/plugin_info_message_filter.cc
  41. 8  renderer_host/plugin_info_message_filter.h
  42. 33  rlz/rlz_extension_api.h
  43. 15  rlz/rlz_extension_apitest.cc
  44. 10  search_engines/search_provider_install_state_message_filter.cc
  45. 5  search_engines/search_provider_install_state_message_filter.h
  46. 3  ssl/ssl_client_auth_requestor_mock.cc
  47. 6  ssl/ssl_client_auth_requestor_mock.h
  48. 3  status_icons/desktop_notification_balloon.cc
  49. 3  user_style_sheet_watcher.cc
  50. 2  webdata/web_data_service_unittest.cc
4  autocomplete/builtin_provider.cc
@@ -46,8 +46,6 @@ BuiltinProvider::BuiltinProvider(ACProviderListener* listener,
46 46
     builtins_.push_back(settings + ASCIIToUTF16(kChromeSettingsSubPages[i]));
47 47
 }
48 48
 
49  
-BuiltinProvider::~BuiltinProvider() {}
50  
-
51 49
 void BuiltinProvider::Start(const AutocompleteInput& input,
52 50
                             bool minimal_changes) {
53 51
   matches_.clear();
@@ -108,6 +106,8 @@ void BuiltinProvider::Start(const AutocompleteInput& input,
108 106
     matches_[i].relevance = kRelevance + matches_.size() - (i + 1);
109 107
 }
110 108
 
  109
+BuiltinProvider::~BuiltinProvider() {}
  110
+
111 111
 void BuiltinProvider::AddMatch(const string16& match_string,
112 112
                                const ACMatchClassifications& styles) {
113 113
   AutocompleteMatch match(this, kRelevance, false,
5  autocomplete/builtin_provider.h
... ...
@@ -1,4 +1,4 @@
1  
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
  1
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 2
 // Use of this source code is governed by a BSD-style license that can be
3 3
 // found in the LICENSE file.
4 4
 //
@@ -22,13 +22,14 @@
22 22
 class BuiltinProvider : public AutocompleteProvider {
23 23
  public:
24 24
   BuiltinProvider(ACProviderListener* listener, Profile* profile);
25  
-  virtual ~BuiltinProvider();
26 25
 
27 26
   // AutocompleteProvider:
28 27
   virtual void Start(const AutocompleteInput& input,
29 28
                      bool minimal_changes) OVERRIDE;
30 29
 
31 30
  private:
  31
+  virtual ~BuiltinProvider();
  32
+
32 33
   typedef std::vector<string16> Builtins;
33 34
 
34 35
   static const int kRelevance;
2  autocomplete/history_provider.cc
@@ -23,6 +23,8 @@ HistoryProvider::HistoryProvider(ACProviderListener* listener,
23 23
       always_prevent_inline_autocomplete_(false) {
24 24
 }
25 25
 
  26
+HistoryProvider::~HistoryProvider() {}
  27
+
26 28
 void HistoryProvider::DeleteMatch(const AutocompleteMatch& match) {
27 29
   DCHECK(done_);
28 30
   DCHECK(profile_);
1  autocomplete/history_provider.h
@@ -19,6 +19,7 @@ class HistoryProvider : public AutocompleteProvider {
19 19
   HistoryProvider(ACProviderListener* listener,
20 20
                   Profile* profile,
21 21
                   const char* name);
  22
+  virtual ~HistoryProvider();
22 23
 
23 24
   // Fixes up user URL input to make it more possible to match against.  Among
24 25
   // many other things, this takes care of the following:
4  autocomplete/history_quick_provider.cc
@@ -102,8 +102,6 @@ HistoryQuickProvider::HistoryQuickProvider(ACProviderListener* listener,
102 102
       inlining_option, NUM_OPTIONS);
103 103
 }
104 104
 
105  
-HistoryQuickProvider::~HistoryQuickProvider() {}
106  
-
107 105
 void HistoryQuickProvider::Start(const AutocompleteInput& input,
108 106
                                  bool minimal_changes) {
109 107
   matches_.clear();
@@ -142,6 +140,8 @@ void HistoryQuickProvider::Start(const AutocompleteInput& input,
142 140
 // TODO(mrossetti): Implement this function. (Will happen in next CL.)
143 141
 void HistoryQuickProvider::DeleteMatch(const AutocompleteMatch& match) {}
144 142
 
  143
+HistoryQuickProvider::~HistoryQuickProvider() {}
  144
+
145 145
 void HistoryQuickProvider::DoAutocomplete() {
146 146
   // Get the matching URLs from the DB.
147 147
   string16 term_string = autocomplete_input_.text();
4  autocomplete/history_quick_provider.h
@@ -24,8 +24,6 @@ class HistoryQuickProvider : public HistoryProvider {
24 24
  public:
25 25
   HistoryQuickProvider(ACProviderListener* listener, Profile* profile);
26 26
 
27  
-  virtual ~HistoryQuickProvider();
28  
-
29 27
   // AutocompleteProvider. |minimal_changes| is ignored since there
30 28
   // is no asynch completion performed.
31 29
   virtual void Start(const AutocompleteInput& input,
@@ -45,6 +43,8 @@ class HistoryQuickProvider : public HistoryProvider {
45 43
   FRIEND_TEST_ALL_PREFIXES(HistoryQuickProviderTest, Spans);
46 44
   FRIEND_TEST_ALL_PREFIXES(HistoryQuickProviderTest, Relevance);
47 45
 
  46
+  virtual ~HistoryQuickProvider();
  47
+
48 48
   // Performs the autocomplete matching and scoring.
49 49
   void DoAutocomplete();
50 50
 
10  autocomplete/shortcuts_provider.cc
@@ -61,11 +61,6 @@ ShortcutsProvider::ShortcutsProvider(ACProviderListener* listener,
61 61
   }
62 62
 }
63 63
 
64  
-ShortcutsProvider::~ShortcutsProvider() {
65  
-  if (shortcuts_backend_.get())
66  
-    shortcuts_backend_->RemoveObserver(this);
67  
-}
68  
-
69 64
 void ShortcutsProvider::Start(const AutocompleteInput& input,
70 65
                               bool minimal_changes) {
71 66
   matches_.clear();
@@ -111,6 +106,11 @@ void ShortcutsProvider::DeleteMatch(const AutocompleteMatch& match) {
111 106
   history_service->DeleteURL(match.destination_url);
112 107
 }
113 108
 
  109
+ShortcutsProvider::~ShortcutsProvider() {
  110
+  if (shortcuts_backend_.get())
  111
+    shortcuts_backend_->RemoveObserver(this);
  112
+}
  113
+
114 114
 void ShortcutsProvider::OnShortcutsLoaded() {
115 115
   initialized_ = true;
116 116
 }
3  autocomplete/shortcuts_provider.h
@@ -26,7 +26,6 @@ class ShortcutsProvider
26 26
       public history::ShortcutsBackend::ShortcutsBackendObserver {
27 27
  public:
28 28
   ShortcutsProvider(ACProviderListener* listener, Profile* profile);
29  
-  virtual ~ShortcutsProvider();
30 29
 
31 30
   // Performs the autocompletion synchronously. Since no asynch completion is
32 31
   // performed |minimal_changes| is ignored.
@@ -41,6 +40,8 @@ class ShortcutsProvider
41 40
   FRIEND_TEST_ALL_PREFIXES(ShortcutsProviderTest, CalculateScore);
42 41
   FRIEND_TEST_ALL_PREFIXES(ShortcutsProviderTest, DeleteMatch);
43 42
 
  43
+  virtual ~ShortcutsProvider();
  44
+
44 45
   // ShortcutsBackendObserver:
45 46
   virtual void OnShortcutsLoaded() OVERRIDE;
46 47
 
3  autocomplete_history_manager_unittest.cc
@@ -29,6 +29,9 @@ class MockWebDataService : public WebDataService {
29 29
  public:
30 30
   MOCK_METHOD1(AddFormFields,
31 31
                void(const std::vector<webkit::forms::FormField>&));  // NOLINT
  32
+
  33
+ protected:
  34
+  virtual ~MockWebDataService() {}
32 35
 };
33 36
 
34 37
 class AutocompleteHistoryManagerTest : public ChromeRenderViewHostTestHarness {
4  autofill/autofill_external_delegate_unittest.cc
@@ -55,13 +55,15 @@ class MockAutofillManager : public AutofillManager {
55 55
  public:
56 56
   explicit MockAutofillManager(TabContentsWrapper* tab_contents)
57 57
       : AutofillManager(tab_contents) {}
58  
-  ~MockAutofillManager() {}
59 58
 
60 59
   MOCK_METHOD4(OnFillAutofillFormData,
61 60
                void(int query_id,
62 61
                     const webkit::forms::FormData& form,
63 62
                     const webkit::forms::FormField& field,
64 63
                     int unique_id));
  64
+
  65
+ protected:
  66
+  virtual ~MockAutofillManager() {}
65 67
 };
66 68
 
67 69
 }  // namespace
5  background/background_contents_service.cc
@@ -61,9 +61,6 @@ class CrashNotificationDelegate : public NotificationDelegate {
61 61
         extension_id_(extension->id()) {
62 62
   }
63 63
 
64  
-  ~CrashNotificationDelegate() {
65  
-  }
66  
-
67 64
   void Display() {}
68 65
 
69 66
   void Error() {}
@@ -93,6 +90,8 @@ class CrashNotificationDelegate : public NotificationDelegate {
93 90
   }
94 91
 
95 92
  private:
  93
+  virtual ~CrashNotificationDelegate() {}
  94
+
96 95
   Profile* profile_;
97 96
   bool is_hosted_app_;
98 97
   std::string extension_id_;
8  chrome_quota_permission_context.cc
@@ -109,11 +109,7 @@ bool RequestQuotaInfoBarDelegate::Cancel() {
109 109
 
110 110
 }  // anonymous namespace
111 111
 
112  
-ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
113  
-}
114  
-
115  
-ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {
116  
-}
  112
+ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {}
117 113
 
118 114
 void ChromeQuotaPermissionContext::RequestQuotaPermission(
119 115
     const GURL& origin_url,
@@ -172,3 +168,5 @@ void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
172 168
 
173 169
   callback.Run(response);
174 170
 }
  171
+
  172
+ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}
4  chrome_quota_permission_context.h
@@ -11,7 +11,6 @@
11 11
 class ChromeQuotaPermissionContext : public content::QuotaPermissionContext {
12 12
  public:
13 13
   ChromeQuotaPermissionContext();
14  
-  virtual ~ChromeQuotaPermissionContext();
15 14
 
16 15
   // The callback will be dispatched on the IO thread.
17 16
   virtual void RequestQuotaPermission(
@@ -25,6 +24,9 @@ class ChromeQuotaPermissionContext : public content::QuotaPermissionContext {
25 24
   void DispatchCallbackOnIOThread(
26 25
       const PermissionCallback& callback,
27 26
       QuotaPermissionResponse response);
  27
+
  28
+ private:
  29
+  virtual ~ChromeQuotaPermissionContext();
28 30
 };
29 31
 
30 32
 #endif  // CHROME_BROWSER_CHROME_QUOTA_PERMISSION_CONTEXT_H_
5  content_settings/cookie_settings.cc
@@ -98,9 +98,6 @@ CookieSettings::CookieSettings(
@@ -227,6 +224,8 @@ ContentSetting CookieSettings::GetCookieSetting(
4  content_settings/cookie_settings.h
@@ -37,8 +37,6 @@ class CookieSettings
@@ -136,6 +134,8 @@ class CookieSettings
819  custom_handlers/protocol_handler_registry.cc
@@ -27,172 +27,224 @@
27 27
 using content::BrowserThread;
28 28
 using content::ChildProcessSecurityPolicy;
29 29
 
30  
-// ProtocolHandlerRegistry -----------------------------------------------------
  30
+namespace {
31 31
 
32  
-ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile,
33  
-    Delegate* delegate)
34  
-    : profile_(profile),
35  
-      delegate_(delegate),
36  
-      enabled_(true),
37  
-      enabled_io_(enabled_),
38  
-      is_loading_(false) {
  32
+// If true default protocol handlers will be removed if the OS level
  33
+// registration for a protocol is no longer Chrome.
  34
+bool ShouldRemoveHandlersNotInOS() {
  35
+#if defined(OS_LINUX)
  36
+  // We don't do this on Linux as the OS registration there is not reliable,
  37
+  // and Chrome OS doesn't have any notion of OS registration.
  38
+  // TODO(benwells): When Linux support is more reliable remove this
  39
+  // difference (http://crbug.com/88255).
  40
+  return false;
  41
+#else
  42
+  return ShellIntegration::CanSetAsDefaultProtocolClient();
  43
+#endif
39 44
 }
40 45
 
41  
-ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {
42  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
43  
-  DCHECK(default_client_observers_.empty());
44  
-}
  46
+} // namespace
45 47
 
46  
-void ProtocolHandlerRegistry::Finalize() {
47  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
48  
-  delegate_.reset(NULL);
49  
-  // We free these now in case there are any outstanding workers running. If
50  
-  // we didn't free them they could respond to workers and try to update the
51  
-  // protocol handler registry after it was deleted.
52  
-  // Observers remove themselves from this list when they are deleted; so
53  
-  // we delete the last item until none are left in the list.
54  
-  while (!default_client_observers_.empty()) {
55  
-    delete default_client_observers_.back();
  48
+static const ProtocolHandler& LookupHandler(
  49
+    const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map,
  50
+    const std::string& scheme) {
  51
+  ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p =
  52
+      handler_map.find(scheme);
  53
+  if (p != handler_map.end()) {
  54
+    return p->second;
56 55
   }
  56
+  return ProtocolHandler::EmptyProtocolHandler();
57 57
 }
58 58
 
59  
-const ProtocolHandlerRegistry::ProtocolHandlerList*
60  
-ProtocolHandlerRegistry::GetHandlerList(
61  
-    const std::string& scheme) const {
62  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63  
-  ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.find(scheme);
64  
-  if (p == protocol_handlers_.end()) {
65  
-    return NULL;
66  
-  }
67  
-  return &p->second;
  59
+// DefaultClientObserver ------------------------------------------------------
  60
+
  61
+ProtocolHandlerRegistry::DefaultClientObserver::DefaultClientObserver(
  62
+    ProtocolHandlerRegistry* registry)
  63
+    : worker_(NULL),
  64
+      registry_(registry) {
  65
+  DCHECK(registry_);
68 66
 }
69 67
 
70  
-ProtocolHandlerRegistry::ProtocolHandlerList
71  
-ProtocolHandlerRegistry::GetHandlersFor(
72  
-    const std::string& scheme) const {
73  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
74  
-  ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.find(scheme);
75  
-  if (p == protocol_handlers_.end()) {
76  
-    return ProtocolHandlerList();
  68
+ProtocolHandlerRegistry::DefaultClientObserver::~DefaultClientObserver() {
  69
+  if (worker_)
  70
+    worker_->ObserverDestroyed();
  71
+
  72
+  DefaultClientObserverList::iterator iter = std::find(
  73
+      registry_->default_client_observers_.begin(),
  74
+      registry_->default_client_observers_.end(), this);
  75
+  registry_->default_client_observers_.erase(iter);
  76
+}
  77
+
  78
+void
  79
+ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState(
  80
+    ShellIntegration::DefaultWebClientUIState state) {
  81
+  if (worker_) {
  82
+    if (ShouldRemoveHandlersNotInOS() &&
  83
+        (state == ShellIntegration::STATE_NOT_DEFAULT)) {
  84
+      registry_->ClearDefault(worker_->protocol());
  85
+    }
  86
+  } else {
  87
+    NOTREACHED();
77 88
   }
78  
-  return p->second;
79 89
 }
80 90
 
81  
-ProtocolHandlerRegistry::ProtocolHandlerList
82  
-ProtocolHandlerRegistry::GetIgnoredHandlers() {
83  
-  return ignored_protocol_handlers_;
  91
+void ProtocolHandlerRegistry::DefaultClientObserver::SetWorker(
  92
+    ShellIntegration::DefaultProtocolClientWorker* worker) {
  93
+  worker_ = worker;
84 94
 }
85 95
 
86  
-void ProtocolHandlerRegistry::RegisterProtocolHandler(
87  
-    const ProtocolHandler& handler) {
88  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
89  
-  DCHECK(CanSchemeBeOverridden(handler.protocol()));
90  
-  DCHECK(!handler.IsEmpty());
91  
-  if (IsRegistered(handler)) {
92  
-    return;
  96
+// Delegate --------------------------------------------------------------------
  97
+
  98
+ProtocolHandlerRegistry::Delegate::~Delegate() {}
  99
+
  100
+void ProtocolHandlerRegistry::Delegate::RegisterExternalHandler(
  101
+    const std::string& protocol) {
  102
+  ChildProcessSecurityPolicy* policy =
  103
+    ChildProcessSecurityPolicy::GetInstance();
  104
+  if (!policy->IsWebSafeScheme(protocol)) {
  105
+    policy->RegisterWebSafeScheme(protocol);
93 106
   }
94  
-  if (enabled_ && !delegate_->IsExternalHandlerRegistered(handler.protocol()))
95  
-    delegate_->RegisterExternalHandler(handler.protocol());
96  
-  InsertHandler(handler);
97 107
 }
98 108
 
99  
-void ProtocolHandlerRegistry::InsertHandler(const ProtocolHandler& handler) {
100  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101  
-  ProtocolHandlerMultiMap::iterator p =
102  
-      protocol_handlers_.find(handler.protocol());
  109
+void ProtocolHandlerRegistry::Delegate::DeregisterExternalHandler(
  110
+    const std::string& protocol) {
  111
+}
103 112
 
104  
-  if (p != protocol_handlers_.end()) {
105  
-    p->second.push_back(handler);
106  
-    return;
107  
-  }
  113
+bool ProtocolHandlerRegistry::Delegate::IsExternalHandlerRegistered(
  114
+    const std::string& protocol) {
  115
+  // NOTE(koz): This function is safe to call from any thread, despite living
  116
+  // in ProfileIOData.
  117
+  return ProfileIOData::IsHandledProtocol(protocol);
  118
+}
108 119
 
109  
-  ProtocolHandlerList new_list;
110  
-  new_list.push_back(handler);
111  
-  protocol_handlers_[handler.protocol()] = new_list;
  120
+ShellIntegration::DefaultProtocolClientWorker*
  121
+ProtocolHandlerRegistry::Delegate::CreateShellWorker(
  122
+    ShellIntegration::DefaultWebClientObserver* observer,
  123
+    const std::string& protocol) {
  124
+  return new ShellIntegration::DefaultProtocolClientWorker(observer, protocol);
112 125
 }
113 126
 
114  
-void ProtocolHandlerRegistry::IgnoreProtocolHandler(
  127
+ProtocolHandlerRegistry::DefaultClientObserver*
  128
+ProtocolHandlerRegistry::Delegate::CreateShellObserver(
  129
+    ProtocolHandlerRegistry* registry) {
  130
+  return new DefaultClientObserver(registry);
  131
+}
  132
+
  133
+void ProtocolHandlerRegistry::Delegate::RegisterWithOSAsDefaultClient(
  134
+    const std::string& protocol, ProtocolHandlerRegistry* registry) {
  135
+  DefaultClientObserver* observer = CreateShellObserver(registry);
  136
+  // The worker pointer is reference counted. While it is running the
  137
+  // message loops of the FILE and UI thread will hold references to it
  138
+  // and it will be automatically freed once all its tasks have finished.
  139
+  scoped_refptr<ShellIntegration::DefaultProtocolClientWorker> worker;
  140
+  worker = CreateShellWorker(observer, protocol);
  141
+  observer->SetWorker(worker);
  142
+  registry->default_client_observers_.push_back(observer);
  143
+  worker->StartSetAsDefault();
  144
+}
  145
+
  146
+// ProtocolHandlerRegistry -----------------------------------------------------
  147
+
  148
+ProtocolHandlerRegistry::ProtocolHandlerRegistry(Profile* profile,
  149
+    Delegate* delegate)
  150
+    : profile_(profile),
  151
+      delegate_(delegate),
  152
+      enabled_(true),
  153
+      enabled_io_(enabled_),
  154
+      is_loading_(false) {
  155
+}
  156
+
  157
+bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest(
  158
+    const ProtocolHandler& handler) {
  159
+  if (handler.IsEmpty() || !CanSchemeBeOverridden(handler.protocol()))
  160
+    return true;
  161
+
  162
+  if (!enabled() || IsRegistered(handler) || HasIgnoredEquivalent(handler))
  163
+    return true;
  164
+
  165
+  if (AttemptReplace(handler))
  166
+    return true;
  167
+
  168
+  return false;
  169
+}
  170
+
  171
+void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler(
115 172
     const ProtocolHandler& handler) {
116 173
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
117  
-  ignored_protocol_handlers_.push_back(handler);
  174
+  RegisterProtocolHandler(handler);
  175
+  SetDefault(handler);
  176
+  Save();
  177
+  NotifyChanged();
118 178
 }
119 179
 
120  
-void ProtocolHandlerRegistry::Enable() {
  180
+void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler(
  181
+    const ProtocolHandler& handler) {
121 182
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
122  
-  if (enabled_) {
123  
-    return;
124  
-  }
125  
-  enabled_ = true;
126  
-  BrowserThread::PostTask(
127  
-      BrowserThread::IO,
128  
-      FROM_HERE,
129  
-      base::Bind(&ProtocolHandlerRegistry::EnableIO, this));
130  
-  ProtocolHandlerMap::const_iterator p;
131  
-  for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) {
132  
-    delegate_->RegisterExternalHandler(p->first);
133  
-  }
  183
+  RegisterProtocolHandler(handler);
134 184
   Save();
135 185
   NotifyChanged();
136 186
 }
137 187
 
138  
-void ProtocolHandlerRegistry::Disable() {
  188
+void ProtocolHandlerRegistry::OnIgnoreRegisterProtocolHandler(
  189
+    const ProtocolHandler& handler) {
139 190
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
140  
-  if (!enabled_) {
141  
-    return;
142  
-  }
143  
-  enabled_ = false;
144  
-  BrowserThread::PostTask(
145  
-      BrowserThread::IO,
146  
-      FROM_HERE,
147  
-      base::Bind(&ProtocolHandlerRegistry::DisableIO, this));
148  
-  ProtocolHandlerMap::const_iterator p;
149  
-  for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) {
150  
-    delegate_->DeregisterExternalHandler(p->first);
151  
-  }
  191
+  IgnoreProtocolHandler(handler);
152 192
   Save();
153 193
   NotifyChanged();
154 194
 }
155 195
 
156  
-std::vector<const DictionaryValue*>
157  
-ProtocolHandlerRegistry::GetHandlersFromPref(const char* pref_name) const {
  196
+bool ProtocolHandlerRegistry::AttemptReplace(const ProtocolHandler& handler) {
158 197
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
159  
-  std::vector<const DictionaryValue*> result;
160  
-  PrefService* prefs = profile_->GetPrefs();
161  
-  if (!prefs->HasPrefPath(pref_name)) {
162  
-    return result;
  198
+  ProtocolHandler old_default = GetHandlerFor(handler.protocol());
  199
+  bool make_new_handler_default = handler.IsSameOrigin(old_default);
  200
+  ProtocolHandlerList to_replace(GetReplacedHandlers(handler));
  201
+  if (to_replace.empty())
  202
+    return false;
  203
+  for (ProtocolHandlerList::iterator p = to_replace.begin();
  204
+       p != to_replace.end(); ++p) {
  205
+    RemoveHandler(*p);
163 206
   }
  207
+  if (make_new_handler_default) {
  208
+    OnAcceptRegisterProtocolHandler(handler);
  209
+  } else {
  210
+    InsertHandler(handler);
  211
+    NotifyChanged();
  212
+  }
  213
+  return true;
  214
+}
164 215
 
165  
-  const ListValue* handlers = prefs->GetList(pref_name);
166  
-  if (handlers) {
167  
-    for (size_t i = 0; i < handlers->GetSize(); ++i) {
168  
-      DictionaryValue* dict;
169  
-      if (!handlers->GetDictionary(i, &dict))
170  
-        continue;
171  
-      if (ProtocolHandler::IsValidDict(dict)) {
172  
-        result.push_back(dict);
173  
-      }
  216
+ProtocolHandlerRegistry::ProtocolHandlerList
  217
+ProtocolHandlerRegistry::GetReplacedHandlers(
  218
+    const ProtocolHandler& handler) const {
  219
+  ProtocolHandlerList replaced_handlers;
  220
+  const ProtocolHandlerList* handlers = GetHandlerList(handler.protocol());
  221
+  if (!handlers)
  222
+    return replaced_handlers;
  223
+  for (ProtocolHandlerList::const_iterator p = handlers->begin();
  224
+       p != handlers->end(); p++) {
  225
+    if (handler.IsSameOrigin(*p)) {
  226
+      replaced_handlers.push_back(*p);
174 227
     }
175 228
   }
176  
-  return result;
  229
+  return replaced_handlers;
177 230
 }
178 231
 
179  
-namespace {
180  
-
181  
-// If true default protocol handlers will be removed if the OS level
182  
-// registration for a protocol is no longer Chrome.
183  
-bool ShouldRemoveHandlersNotInOS() {
184  
-#if defined(OS_LINUX)
185  
-  // We don't do this on Linux as the OS registration there is not reliable,
186  
-  // and Chrome OS doesn't have any notion of OS registration.
187  
-  // TODO(benwells): When Linux support is more reliable remove this
188  
-  // difference (http://crbug.com/88255).
189  
-  return false;
190  
-#else
191  
-  return ShellIntegration::CanSetAsDefaultProtocolClient();
192  
-#endif
  232
+void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) {
  233
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  234
+  default_handlers_.erase(scheme);
  235
+  BrowserThread::PostTask(
  236
+      BrowserThread::IO,
  237
+      FROM_HERE,
  238
+      base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, scheme));
  239
+  Save();
  240
+  NotifyChanged();
193 241
 }
194 242
 
195  
-} // namespace
  243
+bool ProtocolHandlerRegistry::IsDefault(
  244
+    const ProtocolHandler& handler) const {
  245
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  246
+  return GetHandlerFor(handler.protocol()) == handler;
  247
+}
196 248
 
197 249
 void ProtocolHandlerRegistry::Load() {
198 250
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -243,30 +295,38 @@ void ProtocolHandlerRegistry::Load() {
243 295
   }
244 296
 }
245 297
 
246  
-void ProtocolHandlerRegistry::Save() {
  298
+int ProtocolHandlerRegistry::GetHandlerIndex(const std::string& scheme) const {
  299
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  300
+  const ProtocolHandler& handler = GetHandlerFor(scheme);
  301
+  if (handler.IsEmpty())
  302
+    return -1;
  303
+  const ProtocolHandlerList* handlers = GetHandlerList(scheme);
  304
+  if (!handlers)
  305
+    return -1;
  306
+
  307
+  ProtocolHandlerList::const_iterator p;
  308
+  int i;
  309
+  for (i = 0, p = handlers->begin(); p != handlers->end(); ++p, ++i) {
  310
+    if (*p == handler)
  311
+      return i;
  312
+  }
  313
+  return -1;
  314
+}
  315
+
  316
+ProtocolHandlerRegistry::ProtocolHandlerList
  317
+ProtocolHandlerRegistry::GetHandlersFor(
  318
+    const std::string& scheme) const {
247 319
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
248  
-  if (is_loading_) {
249  
-    return;
  320
+  ProtocolHandlerMultiMap::const_iterator p = protocol_handlers_.find(scheme);
  321
+  if (p == protocol_handlers_.end()) {
  322
+    return ProtocolHandlerList();
250 323
   }
251  
-  scoped_ptr<Value> registered_protocol_handlers(EncodeRegisteredHandlers());
252  
-  scoped_ptr<Value> ignored_protocol_handlers(EncodeIgnoredHandlers());
253  
-  scoped_ptr<Value> enabled(Value::CreateBooleanValue(enabled_));
254  
-  profile_->GetPrefs()->Set(prefs::kRegisteredProtocolHandlers,
255  
-      *registered_protocol_handlers);
256  
-  profile_->GetPrefs()->Set(prefs::kIgnoredProtocolHandlers,
257  
-      *ignored_protocol_handlers);
258  
-  profile_->GetPrefs()->Set(prefs::kCustomHandlersEnabled, *enabled);
  324
+  return p->second;
259 325
 }
260 326
 
261  
-bool ProtocolHandlerRegistry::CanSchemeBeOverridden(
262  
-    const std::string& scheme) const {
263  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
264  
-  const ProtocolHandlerList* handlers = GetHandlerList(scheme);
265  
-  // If we already have a handler for this scheme, we can add more.
266  
-  if (handlers != NULL && !handlers->empty())
267  
-    return true;
268  
-  // Don't override a scheme if it already has an external handler.
269  
-  return !delegate_->IsExternalHandlerRegistered(scheme);
  327
+ProtocolHandlerRegistry::ProtocolHandlerList
  328
+ProtocolHandlerRegistry::GetIgnoredHandlers() {
  329
+  return ignored_protocol_handlers_;
270 330
 }
271 331
 
272 332
 void ProtocolHandlerRegistry::GetRegisteredProtocols(
@@ -279,20 +339,15 @@ void ProtocolHandlerRegistry::GetRegisteredProtocols(
279 339
   }
280 340
 }
281 341
 
282  
-void ProtocolHandlerRegistry::RemoveIgnoredHandler(
283  
-    const ProtocolHandler& handler) {
  342
+bool ProtocolHandlerRegistry::CanSchemeBeOverridden(
  343
+    const std::string& scheme) const {
284 344
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
285  
-  bool should_notify = false;
286  
-  ProtocolHandlerList::iterator p = std::find(
287  
-      ignored_protocol_handlers_.begin(), ignored_protocol_handlers_.end(),
288  
-      handler);
289  
-  if (p != ignored_protocol_handlers_.end()) {
290  
-    ignored_protocol_handlers_.erase(p);
291  
-    Save();
292  
-    should_notify = true;
293  
-  }
294  
-  if (should_notify)
295  
-    NotifyChanged();
  345
+  const ProtocolHandlerList* handlers = GetHandlerList(scheme);
  346
+  // If we already have a handler for this scheme, we can add more.
  347
+  if (handlers != NULL && !handlers->empty())
  348
+    return true;
  349
+  // Don't override a scheme if it already has an external handler.
  350
+  return !delegate_->IsExternalHandlerRegistered(scheme);
296 351
 }
297 352
 
298 353
 bool ProtocolHandlerRegistry::IsRegistered(
@@ -306,6 +361,18 @@ bool ProtocolHandlerRegistry::IsRegistered(
306 361
       handlers->end();
307 362
 }
308 363
 
  364
+bool ProtocolHandlerRegistry::IsIgnored(const ProtocolHandler& handler) const {
  365
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  366
+  ProtocolHandlerList::const_iterator i;
  367
+  for (i = ignored_protocol_handlers_.begin();
  368
+       i != ignored_protocol_handlers_.end(); ++i) {
  369
+    if (*i == handler) {
  370
+      return true;
  371
+    }
  372
+  }
  373
+  return false;
  374
+}
  375
+
309 376
 bool ProtocolHandlerRegistry::HasRegisteredEquivalent(
310 377
     const ProtocolHandler& handler) const {
311 378
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -322,29 +389,33 @@ bool ProtocolHandlerRegistry::HasRegisteredEquivalent(
322 389
   return false;
323 390
 }
324 391
 
325  
-bool ProtocolHandlerRegistry::IsIgnored(const ProtocolHandler& handler) const {
  392
+bool ProtocolHandlerRegistry::HasIgnoredEquivalent(
  393
+    const ProtocolHandler& handler) const {
326 394
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
327 395
   ProtocolHandlerList::const_iterator i;
328 396
   for (i = ignored_protocol_handlers_.begin();
329 397
        i != ignored_protocol_handlers_.end(); ++i) {
330  
-    if (*i == handler) {
  398
+    if (handler.IsEquivalent(*i)) {
331 399
       return true;
332 400
     }
333 401
   }
334 402
   return false;
335 403
 }
336 404
 
337  
-bool ProtocolHandlerRegistry::HasIgnoredEquivalent(
338  
-    const ProtocolHandler& handler) const {
  405
+void ProtocolHandlerRegistry::RemoveIgnoredHandler(
  406
+    const ProtocolHandler& handler) {
339 407
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
340  
-  ProtocolHandlerList::const_iterator i;
341  
-  for (i = ignored_protocol_handlers_.begin();
342  
-       i != ignored_protocol_handlers_.end(); ++i) {
343  
-    if (handler.IsEquivalent(*i)) {
344  
-      return true;
345  
-    }
  408
+  bool should_notify = false;
  409
+  ProtocolHandlerList::iterator p = std::find(
  410
+      ignored_protocol_handlers_.begin(), ignored_protocol_handlers_.end(),
  411
+      handler);
  412
+  if (p != ignored_protocol_handlers_.end()) {
  413
+    ignored_protocol_handlers_.erase(p);
  414
+    Save();
  415
+    should_notify = true;
346 416
   }
347  
-  return false;
  417
+  if (should_notify)
  418
+    NotifyChanged();
348 419
 }
349 420
 
350 421
 bool ProtocolHandlerRegistry::IsHandledProtocol(
@@ -353,6 +424,12 @@ bool ProtocolHandlerRegistry::IsHandledProtocol(
353 424
   return enabled_ && !GetHandlerFor(scheme).IsEmpty();
354 425
 }
355 426
 
  427
+bool ProtocolHandlerRegistry::IsHandledProtocolIO(
  428
+    const std::string& scheme) const {
  429
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  430
+  return enabled_io_ && !LookupHandler(default_handlers_io_, scheme).IsEmpty();
  431
+}
  432
+
356 433
 void ProtocolHandlerRegistry::RemoveHandler(
357 434
     const ProtocolHandler& handler) {
358 435
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -391,186 +468,89 @@ void ProtocolHandlerRegistry::RemoveDefaultHandler(const std::string& scheme) {
391 468
     RemoveHandler(current_default);
392 469
 }
393 470
 
394  
-static const ProtocolHandler& LookupHandler(
395  
-    const ProtocolHandlerRegistry::ProtocolHandlerMap& handler_map,
396  
-    const std::string& scheme) {
397  
-  ProtocolHandlerRegistry::ProtocolHandlerMap::const_iterator p =
398  
-      handler_map.find(scheme);
399  
-  if (p != handler_map.end()) {
400  
-    return p->second;
401  
-  }
402  
-  return ProtocolHandler::EmptyProtocolHandler();
403  
-}
404  
-
405  
-Value* ProtocolHandlerRegistry::EncodeRegisteredHandlers() {
406  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
407  
-  ListValue* protocol_handlers = new ListValue();
408  
-  for (ProtocolHandlerMultiMap::iterator i = protocol_handlers_.begin();
409  
-       i != protocol_handlers_.end(); ++i) {
410  
-    for (ProtocolHandlerList::iterator j = i->second.begin();
411  
-         j != i->second.end(); ++j) {
412  
-      DictionaryValue* encoded = j->Encode();
413  
-      if (IsDefault(*j)) {
414  
-        encoded->Set("default", Value::CreateBooleanValue(true));
415  
-      }
416  
-      protocol_handlers->Append(encoded);
417  
-    }
418  
-  }
419  
-  return protocol_handlers;
420  
-}
421  
-
422  
-Value* ProtocolHandlerRegistry::EncodeIgnoredHandlers() {
423  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
424  
-  ListValue* handlers = new ListValue();
425  
-  for (ProtocolHandlerList::iterator i = ignored_protocol_handlers_.begin();
426  
-       i != ignored_protocol_handlers_.end(); ++i) {
427  
-    handlers->Append(i->Encode());
428  
-  }
429  
-  return handlers;
430  
-}
431  
-
432  
-bool ProtocolHandlerRegistry::SilentlyHandleRegisterHandlerRequest(
433  
-    const ProtocolHandler& handler) {
434  
-  if (handler.IsEmpty() || !CanSchemeBeOverridden(handler.protocol()))
435  
-    return true;
436  
-
437  
-  if (!enabled() || IsRegistered(handler) || HasIgnoredEquivalent(handler))
438  
-    return true;
439  
-
440  
-  if (AttemptReplace(handler))
441  
-    return true;
442  
-
443  
-  return false;
444  
-}
445  
-
446  
-void ProtocolHandlerRegistry::OnAcceptRegisterProtocolHandler(
447  
-    const ProtocolHandler& handler) {
448  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
449  
-  RegisterProtocolHandler(handler);
450  
-  SetDefault(handler);
451  
-  Save();
452  
-  NotifyChanged();
453  
-}
454  
-
455  
-void ProtocolHandlerRegistry::OnDenyRegisterProtocolHandler(
456  
-    const ProtocolHandler& handler) {
457  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
458  
-  RegisterProtocolHandler(handler);
459  
-  Save();
460  
-  NotifyChanged();
461  
-}
462  
-
463  
-void ProtocolHandlerRegistry::OnIgnoreRegisterProtocolHandler(
464  
-    const ProtocolHandler& handler) {
  471
+const ProtocolHandler& ProtocolHandlerRegistry::GetHandlerFor(
  472
+    const std::string& scheme) const {
465 473
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
466  
-  IgnoreProtocolHandler(handler);
467  
-  Save();
468  
-  NotifyChanged();
  474
+  return LookupHandler(default_handlers_, scheme);
469 475
 }
470 476
 
471  
-bool ProtocolHandlerRegistry::AttemptReplace(const ProtocolHandler& handler) {
472  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
473  
-  ProtocolHandler old_default = GetHandlerFor(handler.protocol());
474  
-  bool make_new_handler_default = handler.IsSameOrigin(old_default);
475  
-  ProtocolHandlerList to_replace(GetReplacedHandlers(handler));
476  
-  if (to_replace.empty())
477  
-    return false;
478  
-  for (ProtocolHandlerList::iterator p = to_replace.begin();
479  
-       p != to_replace.end(); ++p) {
480  
-    RemoveHandler(*p);
481  
-  }
482  
-  if (make_new_handler_default) {
483  
-    OnAcceptRegisterProtocolHandler(handler);
484  
-  } else {
485  
-    InsertHandler(handler);
486  
-    NotifyChanged();
  477
+net::URLRequestJob* ProtocolHandlerRegistry::MaybeCreateJob(
  478
+    net::URLRequest* request) const {
  479
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  480
+  ProtocolHandler handler = LookupHandler(default_handlers_io_,
  481
+                                          request->url().scheme());
  482
+  if (handler.IsEmpty()) {
  483
+    return NULL;
487 484
   }
488  
-  return true;
489  
-}
490  
-
491  
-ProtocolHandlerRegistry::ProtocolHandlerList
492  
-ProtocolHandlerRegistry::GetReplacedHandlers(
493  
-    const ProtocolHandler& handler) const {
494  
-  ProtocolHandlerList replaced_handlers;
495  
-  const ProtocolHandlerList* handlers = GetHandlerList(handler.protocol());
496  
-  if (!handlers)
497  
-    return replaced_handlers;
498  
-  for (ProtocolHandlerList::const_iterator p = handlers->begin();
499  
-       p != handlers->end(); p++) {
500  
-    if (handler.IsSameOrigin(*p)) {
501  
-      replaced_handlers.push_back(*p);
502  
-    }
  485
+  GURL translated_url(handler.TranslateUrl(request->url()));
  486
+  if (!translated_url.is_valid()) {
  487
+    return NULL;
503 488
   }
504  
-  return replaced_handlers;
505  
-}
506  
-
507  
-
508  
-// static
509  
-void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) {
510  
-  pref_service->RegisterListPref(prefs::kRegisteredProtocolHandlers,
511  
-                                 PrefService::UNSYNCABLE_PREF);
512  
-  pref_service->RegisterListPref(prefs::kIgnoredProtocolHandlers,
513  
-                                 PrefService::UNSYNCABLE_PREF);
514  
-  pref_service->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true,
515  
-                                    PrefService::UNSYNCABLE_PREF);
  489
+  return new net::URLRequestRedirectJob(request, translated_url);
516 490
 }
517 491
 
518  
-void ProtocolHandlerRegistry::SetDefault(const ProtocolHandler& handler) {
  492
+void ProtocolHandlerRegistry::Enable() {
519 493
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
520  
-  ProtocolHandlerMap::const_iterator p = default_handlers_.find(
521  
-      handler.protocol());
522  
-  // If we're not loading, and we are setting a default for a new protocol,
523  
-  // register with the OS.
524  
-  if (!is_loading_ && p == default_handlers_.end())
525  
-      delegate_->RegisterWithOSAsDefaultClient(handler.protocol(), this);
526  
-  default_handlers_.erase(handler.protocol());
527  
-  default_handlers_.insert(std::make_pair(handler.protocol(), handler));
528  
-  PromoteHandler(handler);
  494
+  if (enabled_) {
  495
+    return;
  496
+  }
  497
+  enabled_ = true;
529 498
   BrowserThread::PostTask(
530 499
       BrowserThread::IO,
531 500
       FROM_HERE,
532  
-      base::Bind(&ProtocolHandlerRegistry::SetDefaultIO, this, handler));
  501
+      base::Bind(&ProtocolHandlerRegistry::EnableIO, this));
  502
+  ProtocolHandlerMap::const_iterator p;
  503
+  for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) {
  504
+    delegate_->RegisterExternalHandler(p->first);
  505
+  }
  506
+  Save();
  507
+  NotifyChanged();
533 508
 }
534 509
 
535  
-void ProtocolHandlerRegistry::ClearDefault(const std::string& scheme) {
  510
+void ProtocolHandlerRegistry::Disable() {
536 511
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
537  
-  default_handlers_.erase(scheme);
  512
+  if (!enabled_) {
  513
+    return;
  514
+  }
  515
+  enabled_ = false;
538 516
   BrowserThread::PostTask(
539 517
       BrowserThread::IO,
540 518
       FROM_HERE,
541  
-      base::Bind(&ProtocolHandlerRegistry::ClearDefaultIO, this, scheme));
  519
+      base::Bind(&ProtocolHandlerRegistry::DisableIO, this));
  520
+  ProtocolHandlerMap::const_iterator p;
  521
+  for (p = default_handlers_.begin(); p != default_handlers_.end(); ++p) {
  522
+    delegate_->DeregisterExternalHandler(p->first);
  523
+  }
542 524
   Save();
543 525
   NotifyChanged();
544 526
 }
545 527
 
546  
-bool ProtocolHandlerRegistry::IsDefault(
547  
-    const ProtocolHandler& handler) const {
  528
+void ProtocolHandlerRegistry::Finalize() {
548 529
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
549  
-  return GetHandlerFor(handler.protocol()) == handler;
  530
+  delegate_.reset(NULL);
  531
+  // We free these now in case there are any outstanding workers running. If
  532
+  // we didn't free them they could respond to workers and try to update the
  533
+  // protocol handler registry after it was deleted.
  534
+  // Observers remove themselves from this list when they are deleted; so
  535
+  // we delete the last item until none are left in the list.
  536
+  while (!default_client_observers_.empty()) {
  537
+    delete default_client_observers_.back();
  538
+  }
550 539
 }
551 540
 
552  
-const ProtocolHandler& ProtocolHandlerRegistry::GetHandlerFor(
553  
-    const std::string& scheme) const {
554  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
555  
-  return LookupHandler(default_handlers_, scheme);
  541
+// static
  542
+void ProtocolHandlerRegistry::RegisterPrefs(PrefService* pref_service) {
  543
+  pref_service->RegisterListPref(prefs::kRegisteredProtocolHandlers,
  544
+                                 PrefService::UNSYNCABLE_PREF);
  545
+  pref_service->RegisterListPref(prefs::kIgnoredProtocolHandlers,
  546
+                                 PrefService::UNSYNCABLE_PREF);
  547
+  pref_service->RegisterBooleanPref(prefs::kCustomHandlersEnabled, true,
  548
+                                    PrefService::UNSYNCABLE_PREF);
556 549
 }
557 550
 
558  
-int ProtocolHandlerRegistry::GetHandlerIndex(const std::string& scheme) const {
559  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
560  
-  const ProtocolHandler& handler = GetHandlerFor(scheme);
561  
-  if (handler.IsEmpty())
562  
-    return -1;
563  
-  const ProtocolHandlerList* handlers = GetHandlerList(scheme);
564  
-  if (!handlers)
565  
-    return -1;
566  
-
567  
-  ProtocolHandlerList::const_iterator p;
568  
-  int i;
569  
-  for (i = 0, p = handlers->begin(); p != handlers->end(); ++p, ++i) {
570  
-    if (*p == handler)
571  
-      return i;
572  
-  }
573  
-  return -1;
  551
+ProtocolHandlerRegistry::~ProtocolHandlerRegistry() {
  552
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  553
+  DCHECK(default_client_observers_.empty());
574 554
 }
575 555
 
576 556
 void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) {
@@ -583,16 +563,6 @@ void ProtocolHandlerRegistry::PromoteHandler(const ProtocolHandler& handler) {
583 563
   list.insert(list.begin(), handler);
584 564
 }
585 565
 
586  
-void ProtocolHandlerRegistry::NotifyChanged() {
587  
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
588  
-  content::NotificationService::current()->Notify(
589  
-      chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED,
590  
-      content::Source<Profile>(profile_),
591  
-      content::NotificationService::NoDetails());
592  
-}
593  
-
594  
-// IO thread methods -----------------------------------------------------------
595  
-