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