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

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

Issue 1512007: Disallow display of multiple experimental.extension.popup(...) windows (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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_popup_api.h" 5 #include "chrome/browser/extensions/extension_popup_api.h"
6 6
7 #include "base/json/json_writer.h" 7 #include "base/json/json_writer.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "chrome/browser/extensions/extension_dom_ui.h" 9 #include "chrome/browser/extensions/extension_dom_ui.h"
10 #include "chrome/browser/extensions/extension_host.h" 10 #include "chrome/browser/extensions/extension_host.h"
11 #include "chrome/browser/extensions/extension_message_service.h" 11 #include "chrome/browser/extensions/extension_message_service.h"
12 #include "chrome/browser/browser.h" 12 #include "chrome/browser/browser.h"
13 #include "chrome/browser/browser_window.h" 13 #include "chrome/browser/browser_window.h"
14 #include "chrome/browser/profile.h" 14 #include "chrome/browser/profile.h"
15 #include "chrome/browser/renderer_host/render_view_host.h"
16 #include "chrome/browser/renderer_host/render_view_host_delegate.h"
17 #include "chrome/browser/renderer_host/render_widget_host_view.h"
15 #include "chrome/browser/tab_contents/tab_contents.h" 18 #include "chrome/browser/tab_contents/tab_contents.h"
16 #include "chrome/common/extensions/extension.h" 19 #include "chrome/common/extensions/extension.h"
17 #include "chrome/common/notification_details.h" 20 #include "chrome/common/notification_details.h"
18 #include "chrome/common/notification_service.h" 21 #include "chrome/common/notification_service.h"
19 #include "chrome/common/notification_source.h" 22 #include "chrome/common/notification_source.h"
20 #include "chrome/common/notification_type.h" 23 #include "chrome/common/notification_type.h"
21 #include "chrome/common/url_constants.h" 24 #include "chrome/common/url_constants.h"
22 #include "gfx/point.h" 25 #include "gfx/point.h"
23 26
24 #if defined(TOOLKIT_VIEWS) 27 #if defined(TOOLKIT_VIEWS)
25 #include "chrome/browser/renderer_host/render_view_host.h"
26 #include "chrome/browser/renderer_host/render_view_host_delegate.h"
27 #include "chrome/browser/renderer_host/render_widget_host_view.h"
28 #include "chrome/browser/views/extensions/extension_popup.h" 28 #include "chrome/browser/views/extensions/extension_popup.h"
29 #include "views/view.h" 29 #include "views/view.h"
30 #include "views/focus/focus_manager.h" 30 #include "views/focus/focus_manager.h"
31 #endif // TOOLKIT_VIEWS 31 #endif // TOOLKIT_VIEWS
32 32
33 namespace extension_popup_module_events { 33 namespace extension_popup_module_events {
34 34
35 const char kOnPopupClosed[] = "experimental.popup.onClosed.%d"; 35 const char kOnPopupClosed[] = "experimental.popup.onClosed.%d";
36 36
37 } // namespace extension_popup_module_events 37 } // namespace extension_popup_module_events
38 38
39 namespace { 39 namespace {
40 40
41 // Errors. 41 // Errors.
42 const char kBadAnchorArgument[] = "Invalid anchor argument."; 42 const char kBadAnchorArgument[] = "Invalid anchor argument.";
43 const char kInvalidURLError[] = "Invalid URL."; 43 const char kInvalidURLError[] = "Invalid URL.";
44 const char kNotAnExtension[] = "Not an extension view."; 44 const char kNotAnExtension[] = "Not an extension view.";
45 const char kPopupsDisallowed[] =
46 "Popups are only supported from toolstrip or tab-contents views.";
45 47
46 // Keys. 48 // Keys.
47 const wchar_t kUrlKey[] = L"url"; 49 const wchar_t kUrlKey[] = L"url";
48 const wchar_t kWidthKey[] = L"width"; 50 const wchar_t kWidthKey[] = L"width";
49 const wchar_t kHeightKey[] = L"height"; 51 const wchar_t kHeightKey[] = L"height";
50 const wchar_t kTopKey[] = L"top"; 52 const wchar_t kTopKey[] = L"top";
51 const wchar_t kLeftKey[] = L"left"; 53 const wchar_t kLeftKey[] = L"left";
52 const wchar_t kGiveFocusKey[] = L"giveFocus"; 54 const wchar_t kGiveFocusKey[] = L"giveFocus";
53 const wchar_t kDomAnchorKey[] = L"domAnchor"; 55 const wchar_t kDomAnchorKey[] = L"domAnchor";
54 const wchar_t kBorderStyleKey[] = L"borderStyle"; 56 const wchar_t kBorderStyleKey[] = L"borderStyle";
55 57
56 // chrome enumeration values 58 // chrome enumeration values
57 const char kRectangleChrome[] = "rectangle"; 59 const char kRectangleChrome[] = "rectangle";
58 60
59 }; // namespace 61 }; // namespace
60 62
61 #if defined(TOOLKIT_VIEWS) 63 #if defined(TOOLKIT_VIEWS)
62 // ExtensionPopupHost objects implement the environment necessary to host 64 // ExtensionPopupHost objects implement the environment necessary to host
63 // an ExtensionPopup views for the popup api. Its main job is to handle 65 // an ExtensionPopup views for the popup api. Its main job is to handle
64 // its lifetime and to fire the popup-closed event when the popup is closed. 66 // its lifetime and to fire the popup-closed event when the popup is closed.
65 // Because the close-on-focus-lost behavior is different from page action 67 // Because the close-on-focus-lost behavior is different from page action
66 // and browser action, it also manages its own focus change listening. The 68 // and browser action, it also manages its own focus change listening. The
67 // difference in close-on-focus-lost is that in the page action and browser 69 // difference in close-on-focus-lost is that in the page action and browser
68 // action cases, the popup closes when the focus leaves the popup or any of its 70 // action cases, the popup closes when the focus leaves the popup or any of its
69 // children. In this case, the popup closes when the focus leaves the popups 71 // children. In this case, the popup closes when the focus leaves the popups
70 // containing view or any of *its* children. 72 // containing view or any of *its* children.
71 class ExtensionPopupHost : public ExtensionPopup::Observer, 73 class ExtensionPopupHost : public ExtensionPopup::Observer,
72 public views::WidgetFocusChangeListener, 74 public views::WidgetFocusChangeListener,
73 public base::RefCounted<ExtensionPopupHost> { 75 public base::RefCounted<ExtensionPopupHost>,
76 public NotificationObserver {
74 public: 77 public:
75 explicit ExtensionPopupHost(ExtensionFunctionDispatcher* dispatcher) 78 explicit ExtensionPopupHost(ExtensionFunctionDispatcher* dispatcher)
76 : dispatcher_(dispatcher), popup_(NULL) { 79 : dispatcher_(dispatcher), popup_(NULL) {
77 AddRef(); // Balanced in DispatchPopupClosedEvent(). 80 AddRef(); // Balanced in DispatchPopupClosedEvent().
78 views::FocusManager::GetWidgetFocusManager()->AddFocusChangeListener(this); 81 views::FocusManager::GetWidgetFocusManager()->AddFocusChangeListener(this);
79 } 82 }
80 83
81 ~ExtensionPopupHost() { 84 ~ExtensionPopupHost() {
82 views::FocusManager::GetWidgetFocusManager()-> 85 views::FocusManager::GetWidgetFocusManager()->
83 RemoveFocusChangeListener(this); 86 RemoveFocusChangeListener(this);
84 } 87 }
85 88
86 void set_popup(ExtensionPopup* popup) { 89 void set_popup(ExtensionPopup* popup) {
87 popup_ = popup; 90 popup_ = popup;
91
92 // Now that a popup has been assigned, listen for subsequent popups being
93 // created in the same extension - we want to disallow more than one
94 // concurrently displayed popup windows.
95 registrar_.Add(
96 this,
97 NotificationType::EXTENSION_HOST_CREATED,
98 Source<ExtensionProcessManager>(
99 dispatcher_->profile()->GetExtensionProcessManager()));
88 } 100 }
89 101
90 // Overriden from ExtensionPopup::Observer 102 // Overridden from ExtensionPopup::Observer
91 virtual void ExtensionPopupClosed(ExtensionPopup* popup) { 103 virtual void ExtensionPopupClosed(ExtensionPopup* popup) {
92 // Unregister the automation resource routing registered upon host 104 // Unregister the automation resource routing registered upon host
93 // creation. 105 // creation.
94 AutomationResourceRoutingDelegate* router = 106 AutomationResourceRoutingDelegate* router =
95 GetRoutingFromDispatcher(dispatcher_); 107 GetRoutingFromDispatcher(dispatcher_);
96 if (router) 108 if (router)
97 router->UnregisterRenderViewHost(popup_->host()->render_view_host()); 109 router->UnregisterRenderViewHost(popup_->host()->render_view_host());
98 110
99 // The OnPopupClosed event should be sent later to give the popup time to 111 // The OnPopupClosed event should be sent later to give the popup time to
100 // complete closing. 112 // complete closing.
(...skipping 11 matching lines...) Expand all
112 router->RegisterRenderViewHost(host->render_view_host()); 124 router->RegisterRenderViewHost(host->render_view_host());
113 } 125 }
114 126
115 virtual void DispatchPopupClosedEvent() { 127 virtual void DispatchPopupClosedEvent() {
116 PopupEventRouter::OnPopupClosed( 128 PopupEventRouter::OnPopupClosed(
117 dispatcher_->profile(), dispatcher_->render_view_host()->routing_id()); 129 dispatcher_->profile(), dispatcher_->render_view_host()->routing_id());
118 dispatcher_ = NULL; 130 dispatcher_ = NULL;
119 Release(); // Balanced in ctor. 131 Release(); // Balanced in ctor.
120 } 132 }
121 133
122 // Overriden from views::WidgetFocusChangeListener 134 // Overridden from views::WidgetFocusChangeListener
123 virtual void NativeFocusWillChange(gfx::NativeView focused_before, 135 virtual void NativeFocusWillChange(gfx::NativeView focused_before,
124 gfx::NativeView focused_now) { 136 gfx::NativeView focused_now) {
125 // If no view is to be focused, then Chrome was deactivated, so hide the 137 // If no view is to be focused, then Chrome was deactivated, so hide the
126 // popup. 138 // popup.
127 if (focused_now) { 139 if (focused_now) {
128 gfx::NativeView host_view = 140 gfx::NativeView host_view =
129 dispatcher_->delegate()->GetNativeViewOfHost(); 141 dispatcher_->delegate()->GetNativeViewOfHost();
130 142
131 // If the widget hosting the popup contains the newly focused view, then 143 // If the widget hosting the popup contains the newly focused view, then
132 // don't dismiss the pop-up. 144 // don't dismiss the pop-up.
(...skipping 16 matching lines...) Expand all
149 render_host_view->ContainsNativeView(focused_now)) 161 render_host_view->ContainsNativeView(focused_now))
150 return; 162 return;
151 } 163 }
152 164
153 // We are careful here to let the current event loop unwind before 165 // We are careful here to let the current event loop unwind before
154 // causing the popup to be closed. 166 // causing the popup to be closed.
155 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(popup_, 167 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(popup_,
156 &ExtensionPopup::Close)); 168 &ExtensionPopup::Close));
157 } 169 }
158 170
171 // Overridden from NotificationObserver
172 virtual void Observe(NotificationType type,
173 const NotificationSource& source,
174 const NotificationDetails& details) {
175 DCHECK(NotificationType::EXTENSION_HOST_CREATED == type);
176 if (NotificationType::EXTENSION_HOST_CREATED == type) {
177 Details<ExtensionHost> details_host(details);
178 // Disallow multiple pop-ups from the same extension, by closing
179 // the presently opened popup during construction of any new popups.
180 if (ViewType::EXTENSION_POPUP == details_host->GetRenderViewType() &&
181 popup_->host()->extension() == details_host->extension() &&
182 Details<ExtensionHost>(popup_->host()) != details) {
183 popup_->Close();
184 }
185 }
186 }
187
159 private: 188 private:
160 // Returns the AutomationResourceRoutingDelegate interface for |dispatcher|. 189 // Returns the AutomationResourceRoutingDelegate interface for |dispatcher|.
161 static AutomationResourceRoutingDelegate* 190 static AutomationResourceRoutingDelegate*
162 GetRoutingFromDispatcher(ExtensionFunctionDispatcher* dispatcher) { 191 GetRoutingFromDispatcher(ExtensionFunctionDispatcher* dispatcher) {
163 if (!dispatcher) 192 if (!dispatcher)
164 return NULL; 193 return NULL;
165 194
166 RenderViewHost* render_view_host = dispatcher->render_view_host(); 195 RenderViewHost* render_view_host = dispatcher->render_view_host();
167 RenderViewHostDelegate* delegate = 196 RenderViewHostDelegate* delegate =
168 render_view_host ? render_view_host->delegate() : NULL; 197 render_view_host ? render_view_host->delegate() : NULL;
169 198
170 return delegate ? delegate->GetAutomationResourceRoutingDelegate() : NULL; 199 return delegate ? delegate->GetAutomationResourceRoutingDelegate() : NULL;
171 } 200 }
172 201
173 // A pointer to the dispatcher that handled the request that opened this 202 // A pointer to the dispatcher that handled the request that opened this
174 // popup view. 203 // popup view.
175 ExtensionFunctionDispatcher* dispatcher_; 204 ExtensionFunctionDispatcher* dispatcher_;
176 205
177 // A pointer to the popup. 206 // A pointer to the popup.
178 ExtensionPopup* popup_; 207 ExtensionPopup* popup_;
179 208
209 NotificationRegistrar registrar_;
210
180 DISALLOW_COPY_AND_ASSIGN(ExtensionPopupHost); 211 DISALLOW_COPY_AND_ASSIGN(ExtensionPopupHost);
181 }; 212 };
182 #endif // TOOLKIT_VIEWS 213 #endif // TOOLKIT_VIEWS
183 214
184 PopupShowFunction::PopupShowFunction() 215 PopupShowFunction::PopupShowFunction()
185 #if defined (TOOLKIT_VIEWS) 216 #if defined (TOOLKIT_VIEWS)
186 : popup_(NULL) 217 : popup_(NULL)
187 #endif 218 #endif
188 {} 219 {}
189 220
(...skipping 14 matching lines...) Expand all
204 registrar_.Add(this, NotificationType::EXTENSION_HOST_DESTROYED, 235 registrar_.Add(this, NotificationType::EXTENSION_HOST_DESTROYED,
205 NotificationService::AllSources()); 236 NotificationService::AllSources());
206 } 237 }
207 } 238 }
208 #else 239 #else
209 SendResponse(false); 240 SendResponse(false);
210 #endif 241 #endif
211 } 242 }
212 243
213 bool PopupShowFunction::RunImpl() { 244 bool PopupShowFunction::RunImpl() {
245 // Popups may only be displayed from TAB_CONTENTS and EXTENSION_TOOLSTRIP
246 // views.
247 ViewType::Type view_type =
248 dispatcher()->render_view_host()->delegate()->GetRenderViewType();
249 if (ViewType::EXTENSION_TOOLSTRIP != view_type &&
250 ViewType::TAB_CONTENTS != view_type) {
251 error_ = kPopupsDisallowed;
252 return false;
253 }
254
214 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); 255 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST));
215 const ListValue* args = args_as_list(); 256 const ListValue* args = args_as_list();
216 257
217 std::string url_string; 258 std::string url_string;
218 EXTENSION_FUNCTION_VALIDATE(args->GetString(0, &url_string)); 259 EXTENSION_FUNCTION_VALIDATE(args->GetString(0, &url_string));
219 260
220 DictionaryValue* show_details = NULL; 261 DictionaryValue* show_details = NULL;
221 EXTENSION_FUNCTION_VALIDATE(args->GetDictionary(1, &show_details)); 262 EXTENSION_FUNCTION_VALIDATE(args->GetDictionary(1, &show_details));
222 263
223 DictionaryValue* dom_anchor = NULL; 264 DictionaryValue* dom_anchor = NULL;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 306
266 // Disallow non-extension requests, or requests outside of the requesting 307 // Disallow non-extension requests, or requests outside of the requesting
267 // extension view's extension. 308 // extension view's extension.
268 const std::string& extension_id = url.host(); 309 const std::string& extension_id = url.host();
269 if (extension_id != GetExtension()->id() || 310 if (extension_id != GetExtension()->id() ||
270 !url.SchemeIs(chrome::kExtensionScheme)) { 311 !url.SchemeIs(chrome::kExtensionScheme)) {
271 error_ = kInvalidURLError; 312 error_ = kInvalidURLError;
272 return false; 313 return false;
273 } 314 }
274 315
275 #if defined(TOOLKIT_VIEWS)
276 gfx::Point origin(dom_left, dom_top); 316 gfx::Point origin(dom_left, dom_top);
277 if (!dispatcher()->render_view_host()->view()) { 317 if (!dispatcher()->render_view_host()->view()) {
278 error_ = kNotAnExtension; 318 error_ = kNotAnExtension;
279 return false; 319 return false;
280 } 320 }
281 321
282 gfx::Rect content_bounds = 322 gfx::Rect content_bounds =
283 dispatcher()->render_view_host()->view()->GetViewBounds(); 323 dispatcher()->render_view_host()->view()->GetViewBounds();
284 origin.Offset(content_bounds.x(), content_bounds.y()); 324 origin.Offset(content_bounds.x(), content_bounds.y());
285 gfx::Rect rect(origin.x(), origin.y(), dom_width, dom_height); 325 gfx::Rect rect(origin.x(), origin.y(), dom_width, dom_height);
286 326
287 // Pop-up from extension views (ExtensionShelf, etc.), and drop-down when
288 // in a TabContents view.
289 ViewType::Type view_type =
290 dispatcher()->render_view_host()->delegate()->GetRenderViewType();
291 BubbleBorder::ArrowLocation arrow_location =
292 view_type == ViewType::TAB_CONTENTS ?
293 BubbleBorder::TOP_LEFT : BubbleBorder::BOTTOM_LEFT;
294
295 // Get the correct native window to pass to ExtensionPopup. 327 // Get the correct native window to pass to ExtensionPopup.
296 // ExtensionFunctionDispatcher::Delegate may provide a custom implementation 328 // ExtensionFunctionDispatcher::Delegate may provide a custom implementation
297 // of this. 329 // of this.
298 gfx::NativeWindow window = 330 gfx::NativeWindow window =
299 dispatcher()->delegate()->GetCustomFrameNativeWindow(); 331 dispatcher()->delegate()->GetCustomFrameNativeWindow();
300 if (!window) 332 if (!window)
301 window = GetCurrentBrowser()->window()->GetNativeHandle(); 333 window = GetCurrentBrowser()->window()->GetNativeHandle();
302 334
335 #if defined(TOOLKIT_VIEWS)
336 // Pop-up from extension views (ExtensionShelf, etc.), and drop-down when
337 // in a TabContents view.
338 BubbleBorder::ArrowLocation arrow_location =
339 view_type == ViewType::TAB_CONTENTS ?
340 BubbleBorder::TOP_LEFT : BubbleBorder::BOTTOM_LEFT;
341
303 // ExtensionPopupHost manages it's own lifetime. 342 // ExtensionPopupHost manages it's own lifetime.
304 ExtensionPopupHost* popup_host = new ExtensionPopupHost(dispatcher()); 343 ExtensionPopupHost* popup_host = new ExtensionPopupHost(dispatcher());
305 popup_ = ExtensionPopup::Show(url, 344 popup_ = ExtensionPopup::Show(url,
306 GetCurrentBrowser(), 345 GetCurrentBrowser(),
307 dispatcher()->profile(), 346 dispatcher()->profile(),
308 window, 347 window,
309 rect, 348 rect,
310 arrow_location, 349 arrow_location,
311 give_focus, 350 give_focus,
312 false, // inspect_with_devtools 351 false, // inspect_with_devtools
313 chrome, 352 chrome,
314 popup_host); // ExtensionPopup::Observer 353 popup_host); // ExtensionPopup::Observer
315 354
316 // popup_host will handle focus change listening and close the popup when 355 // popup_host will handle focus change listening and close the popup when
317 // focus leaves the containing views hierarchy. 356 // focus leaves the containing views hierarchy.
318 popup_->set_close_on_lost_focus(false); 357 popup_->set_close_on_lost_focus(false);
319 popup_host->set_popup(popup_); 358 popup_host->set_popup(popup_);
320 #endif // defined(TOOLKIT_VIEWS) 359 #endif // defined(TOOLKIT_VIEWS)
321 return true; 360 return true;
322 } 361 }
323 362
324 void PopupShowFunction::Observe(NotificationType type, 363 void PopupShowFunction::Observe(NotificationType type,
325 const NotificationSource& source, 364 const NotificationSource& source,
326 const NotificationDetails& details) { 365 const NotificationDetails& details) {
327 #if defined(TOOLKIT_VIEWS) 366 #if defined(TOOLKIT_VIEWS)
328 DCHECK(type == NotificationType::EXTENSION_POPUP_VIEW_READY || 367 DCHECK(type == NotificationType::EXTENSION_POPUP_VIEW_READY ||
329 type == NotificationType::EXTENSION_HOST_DESTROYED); 368 type == NotificationType::EXTENSION_HOST_DESTROYED);
330 DCHECK(popup_ != NULL); 369 DCHECK(popup_ != NULL);
331 370
371 // Wait for notification that the popup view is ready (and onload has been
372 // called), before completing the API call.
332 if (popup_ && type == NotificationType::EXTENSION_POPUP_VIEW_READY && 373 if (popup_ && type == NotificationType::EXTENSION_POPUP_VIEW_READY &&
333 Details<ExtensionHost>(popup_->host()) == details) { 374 Details<ExtensionHost>(popup_->host()) == details) {
334 SendResponse(true); 375 SendResponse(true);
335 Release(); // Balanced in Run(). 376 Release(); // Balanced in Run().
336 } else if (popup_ && type == NotificationType::EXTENSION_HOST_DESTROYED && 377 } else if (popup_ && type == NotificationType::EXTENSION_HOST_DESTROYED &&
337 Details<ExtensionHost>(popup_->host()) == details) { 378 Details<ExtensionHost>(popup_->host()) == details) {
338 // If the host was destroyed, then report failure, and release the remaining 379 // If the host was destroyed, then report failure, and release the remaining
339 // reference. 380 // reference.
340 SendResponse(false); 381 SendResponse(false);
341 Release(); // Balanced in Run(). 382 Release(); // Balanced in Run().
342 } 383 }
343 #endif // defined(TOOLKIT_VIEWS) 384 #endif // defined(TOOLKIT_VIEWS)
344 } 385 }
345 386
346 // static 387 // static
347 void PopupEventRouter::OnPopupClosed(Profile* profile, 388 void PopupEventRouter::OnPopupClosed(Profile* profile,
348 int routing_id) { 389 int routing_id) {
349 std::string full_event_name = StringPrintf( 390 std::string full_event_name = StringPrintf(
350 extension_popup_module_events::kOnPopupClosed, 391 extension_popup_module_events::kOnPopupClosed,
351 routing_id); 392 routing_id);
352 393
353 profile->GetExtensionMessageService()->DispatchEventToRenderers( 394 profile->GetExtensionMessageService()->DispatchEventToRenderers(
354 full_event_name, 395 full_event_name,
355 base::JSONWriter::kEmptyArray, 396 base::JSONWriter::kEmptyArray,
356 profile->IsOffTheRecord(), 397 profile->IsOffTheRecord(),
357 GURL()); 398 GURL());
358 } 399 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_host.cc ('k') | chrome/browser/renderer_host/render_view_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698