// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/renderer/pepper/pepper_webplugin_impl.h" #include #include "base/debug/crash_logging.h" #include "base/message_loop/message_loop.h" #include "content/public/common/page_zoom.h" #include "content/public/renderer/content_renderer_client.h" #include "content/renderer/pepper/message_channel.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/plugin_module.h" #include "content/renderer/pepper/v8object_var.h" #include "content/renderer/render_frame_impl.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/var_tracker.h" #include "third_party/WebKit/public/platform/WebPoint.h" #include "third_party/WebKit/public/platform/WebRect.h" #include "third_party/WebKit/public/platform/WebSize.h" #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" #include "third_party/WebKit/public/web/WebBindings.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" #include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "third_party/WebKit/public/web/WebPluginParams.h" #include "third_party/WebKit/public/web/WebPrintParams.h" #include "third_party/WebKit/public/web/WebPrintPresetOptions.h" #include "third_party/WebKit/public/web/WebPrintScalingOption.h" #include "url/gurl.h" using ppapi::V8ObjectVar; using blink::WebCanvas; using blink::WebPlugin; using blink::WebPluginContainer; using blink::WebPluginParams; using blink::WebPoint; using blink::WebPrintParams; using blink::WebRect; using blink::WebSize; using blink::WebString; using blink::WebURL; using blink::WebVector; namespace content { struct PepperWebPluginImpl::InitData { scoped_refptr module; RenderFrameImpl* render_frame; std::vector arg_names; std::vector arg_values; GURL url; }; PepperWebPluginImpl::PepperWebPluginImpl( PluginModule* plugin_module, const WebPluginParams& params, RenderFrameImpl* render_frame, RenderFrame::PluginPowerSaverMode power_saver_mode) : init_data_(new InitData()), full_frame_(params.loadManually), power_saver_mode_(power_saver_mode), instance_object_(PP_MakeUndefined()), container_(NULL) { DCHECK(plugin_module); init_data_->module = plugin_module; init_data_->render_frame = render_frame; for (size_t i = 0; i < params.attributeNames.size(); ++i) { init_data_->arg_names.push_back(params.attributeNames[i].utf8()); init_data_->arg_values.push_back(params.attributeValues[i].utf8()); } init_data_->url = params.url; // Set subresource URL for crash reporting. base::debug::SetCrashKeyValue("subresource_url", init_data_->url.spec()); } PepperWebPluginImpl::~PepperWebPluginImpl() {} blink::WebPluginContainer* PepperWebPluginImpl::container() const { return container_; } bool PepperWebPluginImpl::initialize(WebPluginContainer* container) { // The plugin delegate may have gone away. instance_ = init_data_->module->CreateInstance( init_data_->render_frame, container, init_data_->url); if (!instance_.get()) return false; // Enable script objects for this plugin. container->allowScriptObjects(); bool success = instance_->Initialize(init_data_->arg_names, init_data_->arg_values, full_frame_, power_saver_mode_); if (!success) { instance_->Delete(); instance_ = NULL; blink::WebPlugin* replacement_plugin = GetContentClient()->renderer()->CreatePluginReplacement( init_data_->render_frame, init_data_->module->path()); if (!replacement_plugin || !replacement_plugin->initialize(container)) return false; container->setPlugin(replacement_plugin); return true; } init_data_.reset(); container_ = container; return true; } void PepperWebPluginImpl::destroy() { // Tell |container_| to clear references to this plugin's script objects. if (container_) container_->clearScriptObjects(); if (instance_.get()) { ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(instance_object_); instance_object_ = PP_MakeUndefined(); instance_->Delete(); instance_ = NULL; } base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); } v8::Local PepperWebPluginImpl::v8ScriptableObject( v8::Isolate* isolate) { // Call through the plugin to get its instance object. The plugin should pass // us a reference which we release in destroy(). if (instance_object_.type == PP_VARTYPE_UNDEFINED) instance_object_ = instance_->GetInstanceObject(isolate); // GetInstanceObject talked to the plugin which may have removed the instance // from the DOM, in which case instance_ would be NULL now. if (!instance_.get()) return v8::Local(); scoped_refptr object_var( V8ObjectVar::FromPPVar(instance_object_)); // If there's an InstanceObject, tell the Instance's MessageChannel to pass // any non-postMessage calls to it. if (object_var.get()) { MessageChannel* message_channel = instance_->message_channel(); if (message_channel) message_channel->SetPassthroughObject(object_var->GetHandle()); } v8::Handle result = instance_->GetMessageChannelObject(); return result; } bool PepperWebPluginImpl::getFormValue(WebString& value) { return false; } void PepperWebPluginImpl::paint(WebCanvas* canvas, const WebRect& rect) { if (!instance_->FlashIsFullscreenOrPending()) instance_->Paint(canvas, plugin_rect_, rect); } void PepperWebPluginImpl::updateGeometry( const WebRect& window_rect, const WebRect& clip_rect, const WebVector& cut_outs_rects, bool is_visible) { plugin_rect_ = window_rect; if (!instance_->FlashIsFullscreenOrPending()) { std::vector cut_outs; for (size_t i = 0; i < cut_outs_rects.size(); ++i) cut_outs.push_back(cut_outs_rects[i]); instance_->ViewChanged(plugin_rect_, clip_rect, cut_outs); } } void PepperWebPluginImpl::updateFocus(bool focused) { instance_->SetWebKitFocus(focused); } void PepperWebPluginImpl::updateVisibility(bool visible) {} bool PepperWebPluginImpl::acceptsInputEvents() { return true; } bool PepperWebPluginImpl::handleInputEvent(const blink::WebInputEvent& event, blink::WebCursorInfo& cursor_info) { if (instance_->FlashIsFullscreenOrPending()) return false; return instance_->HandleInputEvent(event, &cursor_info); } void PepperWebPluginImpl::didReceiveResponse( const blink::WebURLResponse& response) { DCHECK(!instance_->document_loader()); instance_->HandleDocumentLoad(response); } void PepperWebPluginImpl::didReceiveData(const char* data, int data_length) { blink::WebURLLoaderClient* document_loader = instance_->document_loader(); if (document_loader) document_loader->didReceiveData(NULL, data, data_length, 0); } void PepperWebPluginImpl::didFinishLoading() { blink::WebURLLoaderClient* document_loader = instance_->document_loader(); if (document_loader) document_loader->didFinishLoading( NULL, 0.0, blink::WebURLLoaderClient::kUnknownEncodedDataLength); } void PepperWebPluginImpl::didFailLoading(const blink::WebURLError& error) { blink::WebURLLoaderClient* document_loader = instance_->document_loader(); if (document_loader) document_loader->didFail(NULL, error); } void PepperWebPluginImpl::didFinishLoadingFrameRequest(const blink::WebURL& url, void* notify_data) {} void PepperWebPluginImpl::didFailLoadingFrameRequest( const blink::WebURL& url, void* notify_data, const blink::WebURLError& error) {} bool PepperWebPluginImpl::hasSelection() const { return !selectionAsText().isEmpty(); } WebString PepperWebPluginImpl::selectionAsText() const { return instance_->GetSelectedText(false); } WebString PepperWebPluginImpl::selectionAsMarkup() const { return instance_->GetSelectedText(true); } WebURL PepperWebPluginImpl::linkAtPosition(const WebPoint& position) const { return GURL(instance_->GetLinkAtPosition(position)); } void PepperWebPluginImpl::setZoomLevel(double level, bool text_only) { instance_->Zoom(content::ZoomLevelToZoomFactor(level), text_only); } bool PepperWebPluginImpl::startFind(const blink::WebString& search_text, bool case_sensitive, int identifier) { return instance_->StartFind(search_text, case_sensitive, identifier); } void PepperWebPluginImpl::selectFindResult(bool forward) { instance_->SelectFindResult(forward); } void PepperWebPluginImpl::stopFind() { instance_->StopFind(); } bool PepperWebPluginImpl::supportsPaginatedPrint() { return instance_->SupportsPrintInterface(); } bool PepperWebPluginImpl::isPrintScalingDisabled() { return instance_->IsPrintScalingDisabled(); } int PepperWebPluginImpl::printBegin(const WebPrintParams& print_params) { return instance_->PrintBegin(print_params); } bool PepperWebPluginImpl::printPage(int page_number, blink::WebCanvas* canvas) { return instance_->PrintPage(page_number, canvas); } void PepperWebPluginImpl::printEnd() { return instance_->PrintEnd(); } bool PepperWebPluginImpl::getPrintPresetOptionsFromDocument( blink::WebPrintPresetOptions* preset_options) { return instance_->GetPrintPresetOptionsFromDocument(preset_options); } bool PepperWebPluginImpl::canRotateView() { return instance_->CanRotateView(); } void PepperWebPluginImpl::rotateView(RotationType type) { instance_->RotateView(type); } bool PepperWebPluginImpl::isPlaceholder() { return false; } } // namespace content