pepper_webplugin_impl.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/pepper/pepper_webplugin_impl.h" 6 7#include <cmath> 8 9#include "base/debug/crash_logging.h" 10#include "base/message_loop/message_loop.h" 11#include "content/public/common/page_zoom.h" 12#include "content/public/renderer/content_renderer_client.h" 13#include "content/renderer/pepper/message_channel.h" 14#include "content/renderer/pepper/npobject_var.h" 15#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 16#include "content/renderer/pepper/plugin_module.h" 17#include "content/renderer/render_frame_impl.h" 18#include "ppapi/shared_impl/ppapi_globals.h" 19#include "ppapi/shared_impl/var_tracker.h" 20#include "third_party/WebKit/public/platform/WebPoint.h" 21#include "third_party/WebKit/public/platform/WebRect.h" 22#include "third_party/WebKit/public/platform/WebSize.h" 23#include "third_party/WebKit/public/platform/WebURLLoaderClient.h" 24#include "third_party/WebKit/public/web/WebBindings.h" 25#include "third_party/WebKit/public/web/WebDocument.h" 26#include "third_party/WebKit/public/web/WebElement.h" 27#include "third_party/WebKit/public/web/WebFrame.h" 28#include "third_party/WebKit/public/web/WebPluginContainer.h" 29#include "third_party/WebKit/public/web/WebPluginParams.h" 30#include "third_party/WebKit/public/web/WebPrintParams.h" 31#include "third_party/WebKit/public/web/WebPrintScalingOption.h" 32#include "url/gurl.h" 33 34using ppapi::NPObjectVar; 35using blink::WebCanvas; 36using blink::WebPlugin; 37using blink::WebPluginContainer; 38using blink::WebPluginParams; 39using blink::WebPoint; 40using blink::WebPrintParams; 41using blink::WebRect; 42using blink::WebSize; 43using blink::WebString; 44using blink::WebURL; 45using blink::WebVector; 46 47namespace content { 48 49struct PepperWebPluginImpl::InitData { 50 scoped_refptr<PluginModule> module; 51 RenderFrameImpl* render_frame; 52 std::vector<std::string> arg_names; 53 std::vector<std::string> arg_values; 54 GURL url; 55}; 56 57PepperWebPluginImpl::PepperWebPluginImpl( 58 PluginModule* plugin_module, 59 const WebPluginParams& params, 60 RenderFrameImpl* render_frame) 61 : init_data_(new InitData()), 62 full_frame_(params.loadManually), 63 instance_object_(PP_MakeUndefined()), 64 container_(NULL) { 65 DCHECK(plugin_module); 66 init_data_->module = plugin_module; 67 init_data_->render_frame = render_frame; 68 for (size_t i = 0; i < params.attributeNames.size(); ++i) { 69 init_data_->arg_names.push_back(params.attributeNames[i].utf8()); 70 init_data_->arg_values.push_back(params.attributeValues[i].utf8()); 71 } 72 init_data_->url = params.url; 73 74 // Set subresource URL for crash reporting. 75 base::debug::SetCrashKeyValue("subresource_url", init_data_->url.spec()); 76} 77 78PepperWebPluginImpl::~PepperWebPluginImpl() { 79} 80 81blink::WebPluginContainer* PepperWebPluginImpl::container() const { 82 return container_; 83} 84 85bool PepperWebPluginImpl::initialize(WebPluginContainer* container) { 86 // The plugin delegate may have gone away. 87 instance_ = init_data_->module->CreateInstance( 88 init_data_->render_frame, container, init_data_->url); 89 if (!instance_.get()) 90 return false; 91 92 // Enable script objects for this plugin. 93 container->allowScriptObjects(); 94 95 bool success = instance_->Initialize(init_data_->arg_names, 96 init_data_->arg_values, 97 full_frame_); 98 if (!success) { 99 instance_->Delete(); 100 instance_ = NULL; 101 102 blink::WebPlugin* replacement_plugin = 103 GetContentClient()->renderer()->CreatePluginReplacement( 104 init_data_->render_frame, init_data_->module->path()); 105 if (!replacement_plugin || !replacement_plugin->initialize(container)) 106 return false; 107 108 container->setPlugin(replacement_plugin); 109 return true; 110 } 111 112 init_data_.reset(); 113 container_ = container; 114 return true; 115} 116 117void PepperWebPluginImpl::destroy() { 118 // Tell |container_| to clear references to this plugin's script objects. 119 if (container_) 120 container_->clearScriptObjects(); 121 122 if (instance_.get()) { 123 ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(instance_object_); 124 instance_object_ = PP_MakeUndefined(); 125 instance_->Delete(); 126 instance_ = NULL; 127 } 128 129 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 130} 131 132NPObject* PepperWebPluginImpl::scriptableObject() { 133 // Call through the plugin to get its instance object. The plugin should pass 134 // us a reference which we release in destroy(). 135 if (instance_object_.type == PP_VARTYPE_UNDEFINED) 136 instance_object_ = instance_->GetInstanceObject(); 137 // GetInstanceObject talked to the plugin which may have removed the instance 138 // from the DOM, in which case instance_ would be NULL now. 139 if (!instance_.get()) 140 return NULL; 141 142 scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(instance_object_)); 143 // If there's an InstanceObject, tell the Instance's MessageChannel to pass 144 // any non-postMessage calls to it. 145 if (object.get()) { 146 instance_->message_channel().SetPassthroughObject(object->np_object()); 147 } 148 NPObject* message_channel_np_object(instance_->message_channel().np_object()); 149 // The object is expected to be retained before it is returned. 150 blink::WebBindings::retainObject(message_channel_np_object); 151 return message_channel_np_object; 152} 153 154NPP PepperWebPluginImpl::pluginNPP() { 155 return instance_->instanceNPP(); 156} 157 158bool PepperWebPluginImpl::getFormValue(WebString& value) { 159 return false; 160} 161 162void PepperWebPluginImpl::paint(WebCanvas* canvas, const WebRect& rect) { 163 if (!instance_->FlashIsFullscreenOrPending()) 164 instance_->Paint(canvas, plugin_rect_, rect); 165} 166 167void PepperWebPluginImpl::updateGeometry( 168 const WebRect& window_rect, 169 const WebRect& clip_rect, 170 const WebVector<WebRect>& cut_outs_rects, 171 bool is_visible) { 172 plugin_rect_ = window_rect; 173 if (!instance_->FlashIsFullscreenOrPending()) { 174 std::vector<gfx::Rect> cut_outs; 175 for (size_t i = 0; i < cut_outs_rects.size(); ++i) 176 cut_outs.push_back(cut_outs_rects[i]); 177 instance_->ViewChanged(plugin_rect_, clip_rect, cut_outs); 178 } 179} 180 181void PepperWebPluginImpl::updateFocus(bool focused) { 182 instance_->SetWebKitFocus(focused); 183} 184 185void PepperWebPluginImpl::updateVisibility(bool visible) { 186} 187 188bool PepperWebPluginImpl::acceptsInputEvents() { 189 return true; 190} 191 192bool PepperWebPluginImpl::handleInputEvent(const blink::WebInputEvent& event, 193 blink::WebCursorInfo& cursor_info) { 194 if (instance_->FlashIsFullscreenOrPending()) 195 return false; 196 return instance_->HandleInputEvent(event, &cursor_info); 197} 198 199void PepperWebPluginImpl::didReceiveResponse( 200 const blink::WebURLResponse& response) { 201 DCHECK(!instance_->document_loader()); 202 instance_->HandleDocumentLoad(response); 203} 204 205void PepperWebPluginImpl::didReceiveData(const char* data, int data_length) { 206 blink::WebURLLoaderClient* document_loader = instance_->document_loader(); 207 if (document_loader) 208 document_loader->didReceiveData(NULL, data, data_length, 0); 209} 210 211void PepperWebPluginImpl::didFinishLoading() { 212 blink::WebURLLoaderClient* document_loader = instance_->document_loader(); 213 if (document_loader) 214 document_loader->didFinishLoading(NULL, 0.0, 215 blink::WebURLLoaderClient::kUnknownEncodedDataLength); 216} 217 218void PepperWebPluginImpl::didFailLoading(const blink::WebURLError& error) { 219 blink::WebURLLoaderClient* document_loader = instance_->document_loader(); 220 if (document_loader) 221 document_loader->didFail(NULL, error); 222} 223 224void PepperWebPluginImpl::didFinishLoadingFrameRequest( 225 const blink::WebURL& url, 226 void* notify_data) { 227} 228 229void PepperWebPluginImpl::didFailLoadingFrameRequest( 230 const blink::WebURL& url, 231 void* notify_data, 232 const blink::WebURLError& error) { 233} 234 235bool PepperWebPluginImpl::hasSelection() const { 236 return !selectionAsText().isEmpty(); 237} 238 239WebString PepperWebPluginImpl::selectionAsText() const { 240 return instance_->GetSelectedText(false); 241} 242 243WebString PepperWebPluginImpl::selectionAsMarkup() const { 244 return instance_->GetSelectedText(true); 245} 246 247WebURL PepperWebPluginImpl::linkAtPosition(const WebPoint& position) const { 248 return GURL(instance_->GetLinkAtPosition(position)); 249} 250 251void PepperWebPluginImpl::setZoomLevel(double level, bool text_only) { 252 instance_->Zoom(content::ZoomLevelToZoomFactor(level), text_only); 253} 254 255bool PepperWebPluginImpl::startFind(const blink::WebString& search_text, 256 bool case_sensitive, 257 int identifier) { 258 return instance_->StartFind(search_text, case_sensitive, identifier); 259} 260 261void PepperWebPluginImpl::selectFindResult(bool forward) { 262 instance_->SelectFindResult(forward); 263} 264 265void PepperWebPluginImpl::stopFind() { 266 instance_->StopFind(); 267} 268 269bool PepperWebPluginImpl::supportsPaginatedPrint() { 270 return instance_->SupportsPrintInterface(); 271} 272 273bool PepperWebPluginImpl::isPrintScalingDisabled() { 274 return instance_->IsPrintScalingDisabled(); 275} 276 277int PepperWebPluginImpl::printBegin(const WebPrintParams& print_params) { 278 return instance_->PrintBegin(print_params); 279} 280 281bool PepperWebPluginImpl::printPage(int page_number, 282 blink::WebCanvas* canvas) { 283 return instance_->PrintPage(page_number, canvas); 284} 285 286void PepperWebPluginImpl::printEnd() { 287 return instance_->PrintEnd(); 288} 289 290bool PepperWebPluginImpl::canRotateView() { 291 return instance_->CanRotateView(); 292} 293 294void PepperWebPluginImpl::rotateView(RotationType type) { 295 instance_->RotateView(type); 296} 297 298bool PepperWebPluginImpl::isPlaceholder() { 299 return false; 300} 301 302} // namespace content 303