Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: chrome/browser/extensions/extension_dom_ui.cc

Issue 174277: override chrome:// URLs via extensions. (Closed)
Patch Set: fix linux errors Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_dom_ui.h" 5 #include "chrome/browser/extensions/extension_dom_ui.h"
6 6
7 #include "chrome/browser/browser.h" 7 #include "chrome/browser/browser.h"
8 #include "chrome/browser/browser_list.h"
9 #include "chrome/browser/profile.h"
8 #include "chrome/browser/tab_contents/tab_contents.h" 10 #include "chrome/browser/tab_contents/tab_contents.h"
9 #include "chrome/common/bindings_policy.h" 11 #include "chrome/common/bindings_policy.h"
12 #include "chrome/common/pref_service.h"
13 #include "chrome/common/url_constants.h"
14
15 namespace {
16 const wchar_t kExtensionURLOverrides[] = L"extensions.chrome_url_overrides";
17 }
10 18
11 ExtensionDOMUI::ExtensionDOMUI(TabContents* tab_contents) 19 ExtensionDOMUI::ExtensionDOMUI(TabContents* tab_contents)
12 : DOMUI(tab_contents) { 20 : DOMUI(tab_contents) {
13 // TODO(aa): It would be cool to show the extension's icon in here. 21 // TODO(aa): It would be cool to show the extension's icon in here.
14 hide_favicon_ = true; 22 hide_favicon_ = true;
15 should_hide_url_ = true; 23 should_hide_url_ = true;
16 bindings_ = BindingsPolicy::EXTENSION; 24 bindings_ = BindingsPolicy::EXTENSION;
25
26 // For chrome:// overrides, some of the defaults are a little different.
27 GURL url = tab_contents->GetURL();
28 if (url.SchemeIs(chrome::kChromeUIScheme)) {
29 if (url.host() == chrome::kChromeUINewTabHost) {
30 focus_location_bar_by_default_ = true;
31 } else {
32 // Current behavior of other chrome:// pages is to display the URL.
33 should_hide_url_ = false;
34 }
35 }
36 }
37
38 void ExtensionDOMUI::ResetExtensionFunctionDispatcher(
39 RenderViewHost* render_view_host) {
40 // Use the NavigationController to get the URL rather than the TabContents
41 // since this is the real underlying URL (see HandleChromeURLOverride).
42 NavigationController& controller = tab_contents()->controller();
43 const GURL& url = controller.pending_entry()->url();
44 extension_function_dispatcher_.reset(
45 new ExtensionFunctionDispatcher(render_view_host, this, url));
17 } 46 }
18 47
19 void ExtensionDOMUI::RenderViewCreated(RenderViewHost* render_view_host) { 48 void ExtensionDOMUI::RenderViewCreated(RenderViewHost* render_view_host) {
20 extension_function_dispatcher_.reset( 49 ResetExtensionFunctionDispatcher(render_view_host);
21 new ExtensionFunctionDispatcher(render_view_host, this,
22 tab_contents()->GetURL()));
23 } 50 }
24 51
25 void ExtensionDOMUI::RenderViewReused(RenderViewHost* render_view_host) { 52 void ExtensionDOMUI::RenderViewReused(RenderViewHost* render_view_host) {
26 extension_function_dispatcher_.reset( 53 ResetExtensionFunctionDispatcher(render_view_host);
27 new ExtensionFunctionDispatcher(render_view_host, this,
28 tab_contents()->GetURL()));
29 } 54 }
30 55
31 void ExtensionDOMUI::ProcessDOMUIMessage(const std::string& message, 56 void ExtensionDOMUI::ProcessDOMUIMessage(const std::string& message,
32 const std::string& content, 57 const std::string& content,
33 int request_id, 58 int request_id,
34 bool has_callback) { 59 bool has_callback) {
35 extension_function_dispatcher_->HandleRequest(message, content, request_id, 60 extension_function_dispatcher_->HandleRequest(message, content, request_id,
36 has_callback); 61 has_callback);
37 } 62 }
38 63
39 Browser* ExtensionDOMUI::GetBrowser() { 64 Browser* ExtensionDOMUI::GetBrowser() {
40 return static_cast<Browser*>(tab_contents()->delegate()); 65 return static_cast<Browser*>(tab_contents()->delegate());
41 } 66 }
67
68 ////////////////////////////////////////////////////////////////////////////////
69 // chrome:// URL overrides
70
71 // static
72 void ExtensionDOMUI::RegisterUserPrefs(PrefService* prefs) {
73 prefs->RegisterDictionaryPref(kExtensionURLOverrides);
74 }
75
76 // static
77 bool ExtensionDOMUI::HandleChromeURLOverride(GURL* url, Profile* profile) {
78 if (!url->SchemeIs(chrome::kChromeUIScheme))
79 return false;
80
81 // Even when the extensions service is enabled by default, it's still
82 // disabled in incognito mode.
83 ExtensionsService* service = profile->GetExtensionsService();
84 if (!service)
85 return false;
86
87 const DictionaryValue* overrides =
88 profile->GetPrefs()->GetDictionary(kExtensionURLOverrides);
89 std::string page = url->host();
90 ListValue* url_list;
91 if (!overrides || !overrides->GetList(UTF8ToWide(page), &url_list))
92 return false;
93
94 if (!service->is_ready()) {
95 // TODO(erikkay) So far, it looks like extensions load before the new tab
96 // page. I don't know if we have anything that enforces this, so add this
97 // check for safety.
98 NOTREACHED() << "Chrome URL override requested before extensions loaded";
99 return false;
100 }
101
102 while (url_list->GetSize()) {
103 Value* val;
104 url_list->Get(0, &val);
105
106 // Verify that the override value is good. If not, unregister it and find
107 // the next one.
108 std::string override;
109 if (!val->GetAsString(&override)) {
110 NOTREACHED();
111 UnregisterChromeURLOverride(page, profile, val);
112 continue;
113 }
114 GURL extension_url(override);
115 if (!extension_url.is_valid()) {
116 NOTREACHED();
117 UnregisterChromeURLOverride(page, profile, val);
118 continue;
119 }
120
121 // Verify that the extension that's being referred to actually exists.
122 Extension* extension = service->GetExtensionByURL(extension_url);
123 if (!extension) {
124 // This can currently happen if you use --load-extension one run, and
125 // then don't use it the next. It could also happen if an extension
126 // were deleted directly from the filesystem, etc.
127 LOG(WARNING) << "chrome URL override present for non-existant extension";
128 UnregisterChromeURLOverride(page, profile, val);
129 continue;
130 }
131
132 *url = extension_url;
133 return true;
134 }
135 return false;
136 }
137
138 // static
139 void ExtensionDOMUI::RegisterChromeURLOverrides(
140 Profile* profile, const DictionaryValue* new_overrides) {
141 if (!new_overrides)
142 return;
143
144 PrefService* prefs = profile->GetPrefs();
145 DictionaryValue* all_overrides =
146 prefs->GetMutableDictionary(kExtensionURLOverrides);
147
148 // For each override provided by the extension, add it to the front of
149 // the override list if it's not already in the list.
150 DictionaryValue::key_iterator iter = new_overrides->begin_keys();
151 for (;iter != new_overrides->end_keys(); ++iter) {
152 Value* val;
153 new_overrides->Get(*iter, &val);
154 std::string string_val;
155 if (!val->GetAsString(&string_val)) {
156 NOTREACHED();
157 continue;
158 }
159 ListValue* page_overrides;
160 if (!all_overrides->GetList(*iter, &page_overrides)) {
161 page_overrides = new ListValue();
162 all_overrides->Set(*iter, page_overrides);
163 } else {
164 // Verify that the override isn't already in the list.
165 ListValue::iterator i = page_overrides->begin();
166 for (; i != page_overrides->end(); ++i) {
167 std::string override_val;
168 if (!(*i)->GetAsString(&override_val)) {
169 NOTREACHED();
170 continue;
171 }
172 if (override_val == string_val)
173 break;
174 }
175 // This value is already in the list, leave it alone.
176 if (i != page_overrides->end())
177 continue;
178 }
179 // Insert the override at the front of the list. Last registered override
180 // wins.
181 page_overrides->Insert(0, val->DeepCopy());
182 }
183 }
184
185 // static
186 void ExtensionDOMUI::UnregisterAndReplaceOverride(const std::string& page,
187 Profile* profile, ListValue* list, Value* override) {
188 int index = list->Remove(*override);
189 if (index == 0) {
190 // This is the active override, so we need to find all existing
191 // tabs for this override and get them to reload the original URL.
192 for (TabContentsIterator iterator; !iterator.done(); iterator++) {
193 TabContents* tab = *iterator;
194 if (tab->profile() != profile)
195 continue;
196
197 GURL url = tab->GetURL();
198 if (!url.SchemeIs(chrome::kChromeUIScheme) || url.host() != page)
199 continue;
200
201 // Don't use Reload() since |url| isn't the same as the internal URL
202 // that NavigationController has.
203 tab->controller().LoadURL(url, url, PageTransition::RELOAD);
204 }
205 }
206 }
207
208 // static
209 void ExtensionDOMUI::UnregisterChromeURLOverride(const std::string& page,
210 Profile* profile, Value* override) {
211 if (!override)
212 return;
213 PrefService* prefs = profile->GetPrefs();
214 DictionaryValue* all_overrides =
215 prefs->GetMutableDictionary(kExtensionURLOverrides);
216 ListValue* page_overrides;
217 if (!all_overrides->GetList(UTF8ToWide(page), &page_overrides)) {
218 // If it's being unregistered, it should already be in the list.
219 NOTREACHED();
220 return;
221 } else {
222 UnregisterAndReplaceOverride(page, profile, page_overrides, override);
223 }
224 }
225
226 // static
227 void ExtensionDOMUI::UnregisterChromeURLOverrides(
228 Profile* profile, const DictionaryValue* new_overrides) {
229 if (!new_overrides)
230 return;
231 PrefService* prefs = profile->GetPrefs();
232 DictionaryValue* all_overrides =
233 prefs->GetMutableDictionary(kExtensionURLOverrides);
234 DictionaryValue::key_iterator iter = new_overrides->begin_keys();
235 for (; iter != new_overrides->end_keys(); ++iter) {
236 Value* val;
237 if (!new_overrides->Get(*iter, &val)) {
238 NOTREACHED();
239 return;
240 }
241 ListValue* page_overrides;
242 if (!all_overrides->GetList(*iter, &page_overrides)) {
243 // If it's being unregistered, it should already be in the list.
244 NOTREACHED();
245 continue;
246 } else {
247 UnregisterAndReplaceOverride(WideToUTF8(*iter), profile, page_overrides,
248 val);
249 }
250 }
251 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_dom_ui.h ('k') | chrome/browser/extensions/extension_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698