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

Side by Side Diff: content/renderer/browser_plugin/browser_plugin.cc

Issue 584713002: Browser Plugin: Remove dependency on NPAPI (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@move_content_window
Patch Set: Updated histograms.xml Created 6 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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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 "content/renderer/browser_plugin/browser_plugin.h" 5 #include "content/renderer/browser_plugin/browser_plugin.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "content/common/browser_plugin/browser_plugin_constants.h" 11 #include "content/common/browser_plugin/browser_plugin_constants.h"
12 #include "content/common/browser_plugin/browser_plugin_messages.h" 12 #include "content/common/browser_plugin/browser_plugin_messages.h"
13 #include "content/common/view_messages.h" 13 #include "content/common/view_messages.h"
14 #include "content/public/common/content_client.h" 14 #include "content/public/common/content_client.h"
15 #include "content/public/common/content_switches.h" 15 #include "content/public/common/content_switches.h"
16 #include "content/public/renderer/browser_plugin_delegate.h" 16 #include "content/public/renderer/browser_plugin_delegate.h"
17 #include "content/public/renderer/content_renderer_client.h" 17 #include "content/public/renderer/content_renderer_client.h"
18 #include "content/renderer/browser_plugin/browser_plugin_bindings.h"
19 #include "content/renderer/browser_plugin/browser_plugin_manager.h" 18 #include "content/renderer/browser_plugin/browser_plugin_manager.h"
20 #include "content/renderer/child_frame_compositing_helper.h" 19 #include "content/renderer/child_frame_compositing_helper.h"
21 #include "content/renderer/cursor_utils.h" 20 #include "content/renderer/cursor_utils.h"
22 #include "content/renderer/drop_data_builder.h" 21 #include "content/renderer/drop_data_builder.h"
23 #include "content/renderer/render_thread_impl.h" 22 #include "content/renderer/render_thread_impl.h"
24 #include "content/renderer/sad_plugin.h" 23 #include "content/renderer/sad_plugin.h"
25 #include "third_party/WebKit/public/platform/WebRect.h" 24 #include "third_party/WebKit/public/platform/WebRect.h"
26 #include "third_party/WebKit/public/web/WebBindings.h"
27 #include "third_party/WebKit/public/web/WebDocument.h"
28 #include "third_party/WebKit/public/web/WebElement.h" 25 #include "third_party/WebKit/public/web/WebElement.h"
29 #include "third_party/WebKit/public/web/WebInputEvent.h" 26 #include "third_party/WebKit/public/web/WebInputEvent.h"
30 #include "third_party/WebKit/public/web/WebPluginContainer.h" 27 #include "third_party/WebKit/public/web/WebPluginContainer.h"
31 #include "third_party/WebKit/public/web/WebPluginParams.h" 28 #include "third_party/WebKit/public/web/WebPluginParams.h"
32 #include "third_party/WebKit/public/web/WebView.h" 29 #include "third_party/WebKit/public/web/WebView.h"
33 #include "third_party/skia/include/core/SkCanvas.h" 30 #include "third_party/skia/include/core/SkCanvas.h"
34 #include "ui/events/keycodes/keyboard_codes.h" 31 #include "ui/events/keycodes/keyboard_codes.h"
35 32
36 using blink::WebCanvas; 33 using blink::WebCanvas;
37 using blink::WebPluginContainer; 34 using blink::WebPluginContainer;
(...skipping 27 matching lines...) Expand all
65 blink::WebFrame* frame, 62 blink::WebFrame* frame,
66 scoped_ptr<BrowserPluginDelegate> delegate) 63 scoped_ptr<BrowserPluginDelegate> delegate)
67 : attached_(false), 64 : attached_(false),
68 attach_pending_(false), 65 attach_pending_(false),
69 render_view_(render_view->AsWeakPtr()), 66 render_view_(render_view->AsWeakPtr()),
70 render_view_routing_id_(render_view->GetRoutingID()), 67 render_view_routing_id_(render_view->GetRoutingID()),
71 container_(NULL), 68 container_(NULL),
72 last_device_scale_factor_(GetDeviceScaleFactor()), 69 last_device_scale_factor_(GetDeviceScaleFactor()),
73 sad_guest_(NULL), 70 sad_guest_(NULL),
74 guest_crashed_(false), 71 guest_crashed_(false),
75 content_window_routing_id_(MSG_ROUTING_NONE),
76 plugin_focused_(false), 72 plugin_focused_(false),
77 visible_(true), 73 visible_(true),
78 mouse_locked_(false), 74 mouse_locked_(false),
79 browser_plugin_manager_(render_view->GetBrowserPluginManager()), 75 browser_plugin_manager_(render_view->GetBrowserPluginManager()),
80 browser_plugin_instance_id_(browser_plugin::kInstanceIDNone), 76 browser_plugin_instance_id_(browser_plugin::kInstanceIDNone),
77 contents_opaque_(true),
81 delegate_(delegate.Pass()), 78 delegate_(delegate.Pass()),
82 weak_ptr_factory_(this) { 79 weak_ptr_factory_(this) {
83 browser_plugin_instance_id_ = browser_plugin_manager()->GetNextInstanceID(); 80 browser_plugin_instance_id_ = browser_plugin_manager()->GetNextInstanceID();
84 81
85 if (delegate_) 82 if (delegate_)
86 delegate_->SetElementInstanceID(browser_plugin_instance_id_); 83 delegate_->SetElementInstanceID(browser_plugin_instance_id_);
87 } 84 }
88 85
89 BrowserPlugin::~BrowserPlugin() { 86 BrowserPlugin::~BrowserPlugin() {
90 browser_plugin_manager()->RemoveBrowserPlugin(browser_plugin_instance_id_); 87 browser_plugin_manager()->RemoveBrowserPlugin(browser_plugin_instance_id_);
91 88
92 if (!ready()) 89 if (!ready())
93 return; 90 return;
94 91
95 browser_plugin_manager()->Send( 92 browser_plugin_manager()->Send(
96 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_, 93 new BrowserPluginHostMsg_PluginDestroyed(render_view_routing_id_,
97 browser_plugin_instance_id_)); 94 browser_plugin_instance_id_));
98 } 95 }
99 96
100 bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) { 97 bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
101 bool handled = true; 98 bool handled = true;
102 IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message) 99 IPC_BEGIN_MESSAGE_MAP(BrowserPlugin, message)
103 IPC_MESSAGE_HANDLER(BrowserPluginMsg_Attach_ACK, OnAttachACK) 100 IPC_MESSAGE_HANDLER(BrowserPluginMsg_Attach_ACK, OnAttachACK)
104 IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus) 101 IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus)
105 IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginMsg_CompositorFrameSwapped, 102 IPC_MESSAGE_HANDLER_GENERIC(BrowserPluginMsg_CompositorFrameSwapped,
106 OnCompositorFrameSwapped(message)) 103 OnCompositorFrameSwapped(message))
107 IPC_MESSAGE_HANDLER(BrowserPluginMsg_CopyFromCompositingSurface, 104 IPC_MESSAGE_HANDLER(BrowserPluginMsg_CopyFromCompositingSurface,
108 OnCopyFromCompositingSurface) 105 OnCopyFromCompositingSurface)
109 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone) 106 IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestGone, OnGuestGone)
107 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetContentsOpaque, OnSetContentsOpaque)
110 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor) 108 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetCursor, OnSetCursor)
111 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetMouseLock, OnSetMouseLock) 109 IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetMouseLock, OnSetMouseLock)
112 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents, 110 IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
113 OnShouldAcceptTouchEvents) 111 OnShouldAcceptTouchEvents)
114 IPC_MESSAGE_UNHANDLED(handled = false) 112 IPC_MESSAGE_UNHANDLED(handled = false)
115 IPC_END_MESSAGE_MAP() 113 IPC_END_MESSAGE_MAP()
116 return handled; 114 return handled;
117 } 115 }
118 116
119 void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name, 117 void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name,
120 const std::string& attribute_value) { 118 const std::string& attribute_value) {
121 if (!container()) 119 if (!container())
122 return; 120 return;
123 121
124 blink::WebElement element = container()->element(); 122 blink::WebElement element = container()->element();
125 blink::WebString web_attribute_name = 123 blink::WebString web_attribute_name =
126 blink::WebString::fromUTF8(attribute_name); 124 blink::WebString::fromUTF8(attribute_name);
127 if (!HasDOMAttribute(attribute_name) || 125 element.setAttribute(web_attribute_name,
128 (std::string(element.getAttribute(web_attribute_name).utf8()) != 126 blink::WebString::fromUTF8(attribute_value));
129 attribute_value)) {
130 element.setAttribute(web_attribute_name,
131 blink::WebString::fromUTF8(attribute_value));
132 }
133 }
134
135 void BrowserPlugin::RemoveDOMAttribute(const std::string& attribute_name) {
136 if (!container())
137 return;
138
139 container()->element().removeAttribute(
140 blink::WebString::fromUTF8(attribute_name));
141 }
142
143 std::string BrowserPlugin::GetDOMAttributeValue(
144 const std::string& attribute_name) const {
145 if (!container())
146 return std::string();
147
148 return container()->element().getAttribute(
149 blink::WebString::fromUTF8(attribute_name)).utf8();
150 }
151
152 bool BrowserPlugin::HasDOMAttribute(const std::string& attribute_name) const {
153 if (!container())
154 return false;
155
156 return container()->element().hasAttribute(
157 blink::WebString::fromUTF8(attribute_name));
158 }
159
160 bool BrowserPlugin::GetAllowTransparencyAttribute() const {
161 return HasDOMAttribute(browser_plugin::kAttributeAllowTransparency);
162 }
163
164 void BrowserPlugin::ParseAllowTransparencyAttribute() {
165 if (!ready())
166 return;
167
168 bool opaque = !GetAllowTransparencyAttribute();
169
170 if (compositing_helper_.get())
171 compositing_helper_->SetContentsOpaque(opaque);
172
173 browser_plugin_manager()->Send(new BrowserPluginHostMsg_SetContentsOpaque(
174 render_view_routing_id_,
175 browser_plugin_instance_id_,
176 opaque));
177 } 127 }
178 128
179 void BrowserPlugin::Attach() { 129 void BrowserPlugin::Attach() {
180 if (ready()) { 130 if (ready()) {
181 attached_ = false; 131 attached_ = false;
182 guest_crashed_ = false; 132 guest_crashed_ = false;
183 EnableCompositing(false); 133 EnableCompositing(false);
184 if (compositing_helper_.get()) { 134 if (compositing_helper_.get()) {
185 compositing_helper_->OnContainerDestroy(); 135 compositing_helper_->OnContainerDestroy();
186 compositing_helper_ = NULL; 136 compositing_helper_ = NULL;
187 } 137 }
188 } 138 }
189 139
190 // TODO(fsamuel): Add support for reattachment. 140 // TODO(fsamuel): Add support for reattachment.
191 BrowserPluginHostMsg_Attach_Params attach_params; 141 BrowserPluginHostMsg_Attach_Params attach_params;
192 attach_params.focused = ShouldGuestBeFocused(); 142 attach_params.focused = ShouldGuestBeFocused();
193 attach_params.visible = visible_; 143 attach_params.visible = visible_;
194 attach_params.opaque = !GetAllowTransparencyAttribute();
195 attach_params.origin = plugin_rect().origin(); 144 attach_params.origin = plugin_rect().origin();
196 gfx::Size view_size(width(), height()); 145 gfx::Size view_size(width(), height());
197 if (!view_size.IsEmpty()) { 146 if (!view_size.IsEmpty()) {
198 PopulateResizeGuestParameters(view_size, 147 PopulateResizeGuestParameters(view_size,
199 &attach_params.resize_guest_params); 148 &attach_params.resize_guest_params);
200 } 149 }
201 browser_plugin_manager()->Send(new BrowserPluginHostMsg_Attach( 150 browser_plugin_manager()->Send(new BrowserPluginHostMsg_Attach(
202 render_view_routing_id_, 151 render_view_routing_id_,
203 browser_plugin_instance_id_, 152 browser_plugin_instance_id_,
204 attach_params)); 153 attach_params));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 // Queue up showing the sad graphic to give content embedders an opportunity 219 // Queue up showing the sad graphic to give content embedders an opportunity
271 // to fire their listeners and potentially overlay the webview with custom 220 // to fire their listeners and potentially overlay the webview with custom
272 // behavior. If the BrowserPlugin is destroyed in the meantime, then the 221 // behavior. If the BrowserPlugin is destroyed in the meantime, then the
273 // task will not be executed. 222 // task will not be executed.
274 base::MessageLoop::current()->PostTask( 223 base::MessageLoop::current()->PostTask(
275 FROM_HERE, 224 FROM_HERE,
276 base::Bind(&BrowserPlugin::ShowSadGraphic, 225 base::Bind(&BrowserPlugin::ShowSadGraphic,
277 weak_ptr_factory_.GetWeakPtr())); 226 weak_ptr_factory_.GetWeakPtr()));
278 } 227 }
279 228
229 void BrowserPlugin::OnSetContentsOpaque(int browser_plugin_instance_id,
230 bool opaque) {
231 if (contents_opaque_ == opaque)
232 return;
233 contents_opaque_ = opaque;
234 if (compositing_helper_.get())
235 compositing_helper_->SetContentsOpaque(opaque);
236 }
237
280 void BrowserPlugin::OnSetCursor(int browser_plugin_instance_id, 238 void BrowserPlugin::OnSetCursor(int browser_plugin_instance_id,
281 const WebCursor& cursor) { 239 const WebCursor& cursor) {
282 cursor_ = cursor; 240 cursor_ = cursor;
283 } 241 }
284 242
285 void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id, 243 void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id,
286 bool enable) { 244 bool enable) {
287 if (enable) { 245 if (enable) {
288 if (mouse_locked_) 246 if (mouse_locked_)
289 return; 247 return;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 } 307 }
350 308
351 WebPluginContainer* BrowserPlugin::container() const { 309 WebPluginContainer* BrowserPlugin::container() const {
352 return container_; 310 return container_;
353 } 311 }
354 312
355 bool BrowserPlugin::initialize(WebPluginContainer* container) { 313 bool BrowserPlugin::initialize(WebPluginContainer* container) {
356 if (!container) 314 if (!container)
357 return false; 315 return false;
358 316
359 // Tell |container| to allow this plugin to use script objects.
360 npp_.reset(new NPP_t);
361 container->allowScriptObjects();
362
363 bindings_.reset(new BrowserPluginBindings(this));
364 container_ = container; 317 container_ = container;
365 container_->setWantsWheelEvents(true); 318 container_->setWantsWheelEvents(true);
366 319
367 g_plugin_container_map.Get().insert(std::make_pair(container_, this)); 320 g_plugin_container_map.Get().insert(std::make_pair(container_, this));
368 321
369 // This is a way to notify observers of our attributes that this plugin is 322 // This is a way to notify observers of our attributes that this plugin is
370 // available in render tree. 323 // available in render tree.
371 // TODO(lazyboy): This should be done through the delegate instead. Perhaps 324 // TODO(lazyboy): This should be done through the delegate instead. Perhaps
372 // by firing an event from there. 325 // by firing an event from there.
373 UpdateDOMAttribute("internalinstanceid", 326 UpdateDOMAttribute("internalinstanceid",
374 base::IntToString(browser_plugin_instance_id_)); 327 base::IntToString(browser_plugin_instance_id_));
375 328
376 browser_plugin_manager()->AddBrowserPlugin(browser_plugin_instance_id_, this); 329 browser_plugin_manager()->AddBrowserPlugin(browser_plugin_instance_id_, this);
377 return true; 330 return true;
378 } 331 }
379 332
380 void BrowserPlugin::EnableCompositing(bool enable) { 333 void BrowserPlugin::EnableCompositing(bool enable) {
381 bool enabled = !!compositing_helper_.get(); 334 bool enabled = !!compositing_helper_.get();
382 if (enabled == enable) 335 if (enabled == enable)
383 return; 336 return;
384 337
385 if (enable) { 338 if (enable) {
386 DCHECK(!compositing_helper_.get()); 339 DCHECK(!compositing_helper_.get());
387 if (!compositing_helper_.get()) { 340 if (!compositing_helper_.get()) {
388 compositing_helper_ = ChildFrameCompositingHelper::CreateForBrowserPlugin( 341 compositing_helper_ = ChildFrameCompositingHelper::CreateForBrowserPlugin(
389 weak_ptr_factory_.GetWeakPtr()); 342 weak_ptr_factory_.GetWeakPtr());
390 } 343 }
391 } 344 }
392 compositing_helper_->EnableCompositing(enable); 345 compositing_helper_->EnableCompositing(enable);
393 compositing_helper_->SetContentsOpaque(!GetAllowTransparencyAttribute()); 346 compositing_helper_->SetContentsOpaque(contents_opaque_);
394 347
395 if (!enable) { 348 if (!enable) {
396 DCHECK(compositing_helper_.get()); 349 DCHECK(compositing_helper_.get());
397 compositing_helper_->OnContainerDestroy(); 350 compositing_helper_->OnContainerDestroy();
398 compositing_helper_ = NULL; 351 compositing_helper_ = NULL;
399 } 352 }
400 } 353 }
401 354
402 void BrowserPlugin::destroy() { 355 void BrowserPlugin::destroy() {
403 // If the plugin was initialized then it has a valid |npp_| identifier, and
404 // the |container_| must clear references to the plugin's script objects.
405 DCHECK(!npp_ || container_);
406 if (container_) { 356 if (container_) {
407 container_->clearScriptObjects(); 357 //container_->clearScriptObjects();
408 358
409 // The BrowserPlugin's WebPluginContainer is deleted immediately after this 359 // The BrowserPlugin's WebPluginContainer is deleted immediately after this
410 // call returns, so let's not keep a reference to it around. 360 // call returns, so let's not keep a reference to it around.
411 g_plugin_container_map.Get().erase(container_); 361 g_plugin_container_map.Get().erase(container_);
412 } 362 }
413 363
414 if (compositing_helper_.get()) 364 if (compositing_helper_.get())
415 compositing_helper_->OnContainerDestroy(); 365 compositing_helper_->OnContainerDestroy();
416 container_ = NULL; 366 container_ = NULL;
417 // Will be a no-op if the mouse is not currently locked. 367 // Will be a no-op if the mouse is not currently locked.
418 if (render_view_) 368 if (render_view_)
419 render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this); 369 render_view_->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
420 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 370 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
421 } 371 }
422 372
423 NPObject* BrowserPlugin::scriptableObject() {
424 if (!bindings_)
425 return NULL;
426
427 NPObject* browser_plugin_np_object(bindings_->np_object());
428 // The object is expected to be retained before it is returned.
429 blink::WebBindings::retainObject(browser_plugin_np_object);
430 return browser_plugin_np_object;
431 }
432
433 NPP BrowserPlugin::pluginNPP() {
434 return npp_.get();
435 }
436
437 bool BrowserPlugin::supportsKeyboardFocus() const { 373 bool BrowserPlugin::supportsKeyboardFocus() const {
438 return true; 374 return true;
439 } 375 }
440 376
441 bool BrowserPlugin::supportsEditCommands() const { 377 bool BrowserPlugin::supportsEditCommands() const {
442 return true; 378 return true;
443 } 379 }
444 380
445 bool BrowserPlugin::supportsInputMethod() const { 381 bool BrowserPlugin::supportsInputMethod() const {
446 return true; 382 return true;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 416
481 // static 417 // static
482 bool BrowserPlugin::ShouldForwardToBrowserPlugin( 418 bool BrowserPlugin::ShouldForwardToBrowserPlugin(
483 const IPC::Message& message) { 419 const IPC::Message& message) {
484 switch (message.type()) { 420 switch (message.type()) {
485 case BrowserPluginMsg_Attach_ACK::ID: 421 case BrowserPluginMsg_Attach_ACK::ID:
486 case BrowserPluginMsg_AdvanceFocus::ID: 422 case BrowserPluginMsg_AdvanceFocus::ID:
487 case BrowserPluginMsg_CompositorFrameSwapped::ID: 423 case BrowserPluginMsg_CompositorFrameSwapped::ID:
488 case BrowserPluginMsg_CopyFromCompositingSurface::ID: 424 case BrowserPluginMsg_CopyFromCompositingSurface::ID:
489 case BrowserPluginMsg_GuestGone::ID: 425 case BrowserPluginMsg_GuestGone::ID:
426 case BrowserPluginMsg_SetContentsOpaque::ID:
490 case BrowserPluginMsg_SetCursor::ID: 427 case BrowserPluginMsg_SetCursor::ID:
491 case BrowserPluginMsg_SetMouseLock::ID: 428 case BrowserPluginMsg_SetMouseLock::ID:
492 case BrowserPluginMsg_ShouldAcceptTouchEvents::ID: 429 case BrowserPluginMsg_ShouldAcceptTouchEvents::ID:
493 return true; 430 return true;
494 default: 431 default:
495 break; 432 break;
496 } 433 }
497 return false; 434 return false;
498 } 435 }
499 436
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 const blink::WebMouseEvent& event) { 653 const blink::WebMouseEvent& event) {
717 browser_plugin_manager()->Send( 654 browser_plugin_manager()->Send(
718 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, 655 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_,
719 browser_plugin_instance_id_, 656 browser_plugin_instance_id_,
720 plugin_rect_, 657 plugin_rect_,
721 &event)); 658 &event));
722 return true; 659 return true;
723 } 660 }
724 661
725 } // namespace content 662 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/browser_plugin/browser_plugin.h ('k') | content/renderer/browser_plugin/browser_plugin_bindings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698