| Index: content/renderer/pepper/pepper_plugin_delegate_impl.cc
|
| ===================================================================
|
| --- content/renderer/pepper/pepper_plugin_delegate_impl.cc (revision 214411)
|
| +++ content/renderer/pepper/pepper_plugin_delegate_impl.cc (working copy)
|
| @@ -1,852 +0,0 @@
|
| -// 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_plugin_delegate_impl.h"
|
| -
|
| -#include <cmath>
|
| -#include <cstddef>
|
| -#include <map>
|
| -#include <queue>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/callback.h"
|
| -#include "base/command_line.h"
|
| -#include "base/files/file_path.h"
|
| -#include "base/files/file_util_proxy.h"
|
| -#include "base/logging.h"
|
| -#include "base/platform_file.h"
|
| -#include "base/strings/string_split.h"
|
| -#include "base/sync_socket.h"
|
| -#include "base/time/time.h"
|
| -#include "content/child/child_process.h"
|
| -#include "content/child/npapi/webplugin.h"
|
| -#include "content/common/child_process_messages.h"
|
| -#include "content/common/gpu/client/context_provider_command_buffer.h"
|
| -#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
|
| -#include "content/common/pepper_messages.h"
|
| -#include "content/common/view_messages.h"
|
| -#include "content/public/common/content_switches.h"
|
| -#include "content/public/common/context_menu_params.h"
|
| -#include "content/public/common/media_stream_request.h"
|
| -#include "content/public/common/page_zoom.h"
|
| -#include "content/public/common/referrer.h"
|
| -#include "content/public/common/webplugininfo.h"
|
| -#include "content/public/renderer/content_renderer_client.h"
|
| -#include "content/renderer/gamepad_shared_memory_reader.h"
|
| -#include "content/renderer/media/media_stream_dispatcher.h"
|
| -#include "content/renderer/p2p/socket_dispatcher.h"
|
| -#include "content/renderer/pepper/content_renderer_pepper_host_factory.h"
|
| -#include "content/renderer/pepper/host_dispatcher_wrapper.h"
|
| -#include "content/renderer/pepper/pepper_broker.h"
|
| -#include "content/renderer/pepper/pepper_browser_connection.h"
|
| -#include "content/renderer/pepper/pepper_file_system_host.h"
|
| -#include "content/renderer/pepper/pepper_graphics_2d_host.h"
|
| -#include "content/renderer/pepper/pepper_hung_plugin_filter.h"
|
| -#include "content/renderer/pepper/pepper_in_process_resource_creation.h"
|
| -#include "content/renderer/pepper/pepper_in_process_router.h"
|
| -#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
|
| -#include "content/renderer/pepper/pepper_plugin_registry.h"
|
| -#include "content/renderer/pepper/pepper_url_loader_host.h"
|
| -#include "content/renderer/pepper/pepper_webplugin_impl.h"
|
| -#include "content/renderer/pepper/plugin_module.h"
|
| -#include "content/renderer/pepper/ppb_tcp_server_socket_private_impl.h"
|
| -#include "content/renderer/pepper/ppb_tcp_socket_private_impl.h"
|
| -#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
|
| -#include "content/renderer/pepper/resource_helper.h"
|
| -#include "content/renderer/pepper/url_response_info_util.h"
|
| -#include "content/renderer/render_thread_impl.h"
|
| -#include "content/renderer/render_view_impl.h"
|
| -#include "content/renderer/render_widget_fullscreen_pepper.h"
|
| -#include "content/renderer/webplugin_delegate_proxy.h"
|
| -#include "ipc/ipc_channel_handle.h"
|
| -#include "ipc/ipc_platform_file.h"
|
| -#include "media/video/capture/video_capture_proxy.h"
|
| -#include "ppapi/c/dev/pp_video_dev.h"
|
| -#include "ppapi/c/pp_errors.h"
|
| -#include "ppapi/c/private/ppb_flash.h"
|
| -#include "ppapi/proxy/ppapi_messages.h"
|
| -#include "ppapi/proxy/url_loader_resource.h"
|
| -#include "ppapi/shared_impl/api_id.h"
|
| -#include "ppapi/shared_impl/file_path.h"
|
| -#include "ppapi/shared_impl/platform_file.h"
|
| -#include "ppapi/shared_impl/ppapi_globals.h"
|
| -#include "ppapi/shared_impl/ppapi_preferences.h"
|
| -#include "ppapi/shared_impl/ppb_device_ref_shared.h"
|
| -#include "ppapi/shared_impl/ppp_instance_combined.h"
|
| -#include "ppapi/shared_impl/resource_tracker.h"
|
| -#include "ppapi/shared_impl/socket_option_data.h"
|
| -#include "ppapi/thunk/enter.h"
|
| -#include "ppapi/thunk/ppb_tcp_server_socket_private_api.h"
|
| -#include "third_party/WebKit/public/web/WebCursorInfo.h"
|
| -#include "third_party/WebKit/public/web/WebFrame.h"
|
| -#include "third_party/WebKit/public/web/WebInputEvent.h"
|
| -#include "third_party/WebKit/public/web/WebScreenInfo.h"
|
| -#include "third_party/WebKit/public/web/WebView.h"
|
| -#include "ui/gfx/size.h"
|
| -#include "url/gurl.h"
|
| -
|
| -using WebKit::WebFrame;
|
| -
|
| -namespace content {
|
| -
|
| -namespace {
|
| -
|
| -void CreateHostForInProcessModule(RenderViewImpl* render_view,
|
| - PluginModule* module,
|
| - const WebPluginInfo& webplugin_info) {
|
| - // First time an in-process plugin was used, make a host for it.
|
| - const PepperPluginInfo* info =
|
| - PepperPluginRegistry::GetInstance()->GetInfoForPlugin(webplugin_info);
|
| - DCHECK(!info->is_out_of_process);
|
| -
|
| - ppapi::PpapiPermissions perms(
|
| - PepperPluginRegistry::GetInstance()->GetInfoForPlugin(
|
| - webplugin_info)->permissions);
|
| - RendererPpapiHostImpl* host_impl =
|
| - RendererPpapiHostImpl::CreateOnModuleForInProcess(
|
| - module, perms);
|
| - render_view->PpapiPluginCreated(host_impl);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderViewImpl* render_view)
|
| - : RenderViewObserver(render_view),
|
| - render_view_(render_view),
|
| - pepper_browser_connection_(this),
|
| - focused_plugin_(NULL),
|
| - last_mouse_event_target_(NULL) {
|
| -}
|
| -
|
| -PepperPluginDelegateImpl::~PepperPluginDelegateImpl() {
|
| -}
|
| -
|
| -WebKit::WebPlugin* PepperPluginDelegateImpl::CreatePepperWebPlugin(
|
| - const WebPluginInfo& webplugin_info,
|
| - const WebKit::WebPluginParams& params) {
|
| - bool pepper_plugin_was_registered = false;
|
| - scoped_refptr<PluginModule> pepper_module(
|
| - CreatePepperPluginModule(webplugin_info, &pepper_plugin_was_registered));
|
| -
|
| - if (pepper_plugin_was_registered) {
|
| - if (!pepper_module.get())
|
| - return NULL;
|
| - return new PepperWebPluginImpl(
|
| - pepper_module.get(), params, AsWeakPtr(), render_view_->AsWeakPtr());
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -scoped_refptr<PluginModule> PepperPluginDelegateImpl::CreatePepperPluginModule(
|
| - const WebPluginInfo& webplugin_info,
|
| - bool* pepper_plugin_was_registered) {
|
| - *pepper_plugin_was_registered = true;
|
| -
|
| - // See if a module has already been loaded for this plugin.
|
| - base::FilePath path(webplugin_info.path);
|
| - scoped_refptr<PluginModule> module =
|
| - PepperPluginRegistry::GetInstance()->GetLiveModule(path);
|
| - if (module.get()) {
|
| - if (!module->renderer_ppapi_host()) {
|
| - // If the module exists and no embedder state was associated with it,
|
| - // then the module was one of the ones preloaded and is an in-process
|
| - // plugin. We need to associate our host state with it.
|
| - CreateHostForInProcessModule(render_view_, module.get(), webplugin_info);
|
| - }
|
| - return module;
|
| - }
|
| -
|
| - // In-process plugins will have always been created up-front to avoid the
|
| - // sandbox restrictions. So getting here implies it doesn't exist or should
|
| - // be out of process.
|
| - const PepperPluginInfo* info =
|
| - PepperPluginRegistry::GetInstance()->GetInfoForPlugin(webplugin_info);
|
| - if (!info) {
|
| - *pepper_plugin_was_registered = false;
|
| - return scoped_refptr<PluginModule>();
|
| - } else if (!info->is_out_of_process) {
|
| - // In-process plugin not preloaded, it probably couldn't be initialized.
|
| - return scoped_refptr<PluginModule>();
|
| - }
|
| -
|
| - ppapi::PpapiPermissions permissions =
|
| - ppapi::PpapiPermissions::GetForCommandLine(info->permissions);
|
| -
|
| - // Out of process: have the browser start the plugin process for us.
|
| - IPC::ChannelHandle channel_handle;
|
| - base::ProcessId peer_pid;
|
| - int plugin_child_id = 0;
|
| - Send(new ViewHostMsg_OpenChannelToPepperPlugin(
|
| - path, &channel_handle, &peer_pid, &plugin_child_id));
|
| - if (channel_handle.name.empty()) {
|
| - // Couldn't be initialized.
|
| - return scoped_refptr<PluginModule>();
|
| - }
|
| -
|
| - // AddLiveModule must be called before any early returns since the
|
| - // module's destructor will remove itself.
|
| - module = new PluginModule(info->name, path, permissions);
|
| - PepperPluginRegistry::GetInstance()->AddLiveModule(path, module.get());
|
| -
|
| - if (!CreateOutOfProcessModule(module.get(),
|
| - path,
|
| - permissions,
|
| - channel_handle,
|
| - peer_pid,
|
| - plugin_child_id,
|
| - false)) // is_external = false
|
| - return scoped_refptr<PluginModule>();
|
| -
|
| - return module;
|
| -}
|
| -
|
| -scoped_refptr<PepperBroker> PepperPluginDelegateImpl::CreateBroker(
|
| - PluginModule* plugin_module) {
|
| - DCHECK(plugin_module);
|
| - DCHECK(!plugin_module->GetBroker());
|
| -
|
| - // The broker path is the same as the plugin.
|
| - const base::FilePath& broker_path = plugin_module->path();
|
| -
|
| - scoped_refptr<PepperBroker> broker = new PepperBroker(plugin_module, this);
|
| -
|
| - int request_id =
|
| - pending_connect_broker_.Add(new scoped_refptr<PepperBroker>(broker));
|
| -
|
| - // Have the browser start the broker process for us.
|
| - Send(new ViewHostMsg_OpenChannelToPpapiBroker(
|
| - routing_id(), request_id, broker_path));
|
| -
|
| - return broker;
|
| -}
|
| -
|
| -RendererPpapiHost* PepperPluginDelegateImpl::CreateOutOfProcessModule(
|
| - PluginModule* module,
|
| - const base::FilePath& path,
|
| - ppapi::PpapiPermissions permissions,
|
| - const IPC::ChannelHandle& channel_handle,
|
| - base::ProcessId peer_pid,
|
| - int plugin_child_id,
|
| - bool is_external) {
|
| - scoped_refptr<PepperHungPluginFilter> hung_filter(
|
| - new PepperHungPluginFilter(path, routing_id(), plugin_child_id));
|
| - scoped_ptr<HostDispatcherWrapper> dispatcher(
|
| - new HostDispatcherWrapper(module,
|
| - peer_pid,
|
| - plugin_child_id,
|
| - permissions,
|
| - is_external));
|
| - if (!dispatcher->Init(
|
| - channel_handle,
|
| - PluginModule::GetLocalGetInterfaceFunc(),
|
| - ppapi::Preferences(render_view_->webkit_preferences()),
|
| - hung_filter.get()))
|
| - return NULL;
|
| -
|
| - RendererPpapiHostImpl* host_impl =
|
| - RendererPpapiHostImpl::CreateOnModuleForOutOfProcess(
|
| - module, dispatcher->dispatcher(), permissions);
|
| - render_view_->PpapiPluginCreated(host_impl);
|
| -
|
| - module->InitAsProxied(dispatcher.release());
|
| - return host_impl;
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnPpapiBrokerChannelCreated(
|
| - int request_id,
|
| - base::ProcessId broker_pid,
|
| - const IPC::ChannelHandle& handle) {
|
| - scoped_refptr<PepperBroker>* broker_ptr =
|
| - pending_connect_broker_.Lookup(request_id);
|
| - if (broker_ptr) {
|
| - scoped_refptr<PepperBroker> broker = *broker_ptr;
|
| - pending_connect_broker_.Remove(request_id);
|
| - broker->OnBrokerChannelConnected(broker_pid, handle);
|
| - } else {
|
| - // There is no broker waiting for this channel. Close it so the broker can
|
| - // clean up and possibly exit.
|
| - // The easiest way to clean it up is to just put it in an object
|
| - // and then close them. This failure case is not performance critical.
|
| - PepperBrokerDispatcherWrapper temp_dispatcher;
|
| - temp_dispatcher.Init(broker_pid, handle);
|
| - }
|
| -}
|
| -
|
| -// Iterates through pending_connect_broker_ to find the broker.
|
| -// Cannot use Lookup() directly because pending_connect_broker_ does not store
|
| -// the raw pointer to the broker. Assumes maximum of one copy of broker exists.
|
| -bool PepperPluginDelegateImpl::StopWaitingForBrokerConnection(
|
| - PepperBroker* broker) {
|
| - for (BrokerMap::iterator i(&pending_connect_broker_);
|
| - !i.IsAtEnd(); i.Advance()) {
|
| - if (i.GetCurrentValue()->get() == broker) {
|
| - pending_connect_broker_.Remove(i.GetCurrentKey());
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::ViewWillInitiatePaint() {
|
| - // Notify all of our instances that we started painting. This is used for
|
| - // internal bookkeeping only, so we know that the set can not change under
|
| - // us.
|
| - for (std::set<PepperPluginInstanceImpl*>::iterator i =
|
| - active_instances_.begin();
|
| - i != active_instances_.end(); ++i)
|
| - (*i)->ViewWillInitiatePaint();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::ViewInitiatedPaint() {
|
| - // Notify all instances that we painted. The same caveats apply as for
|
| - // ViewFlushedPaint regarding instances closing themselves, so we take
|
| - // similar precautions.
|
| - std::set<PepperPluginInstanceImpl*> plugins = active_instances_;
|
| - for (std::set<PepperPluginInstanceImpl*>::iterator i = plugins.begin();
|
| - i != plugins.end(); ++i) {
|
| - if (active_instances_.find(*i) != active_instances_.end())
|
| - (*i)->ViewInitiatedPaint();
|
| - }
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::ViewFlushedPaint() {
|
| - // Notify all instances that we flushed. This will call into the plugin, and
|
| - // we it may ask to close itself as a result. This will, in turn, modify our
|
| - // set, possibly invalidating the iterator. So we iterate on a copy that
|
| - // won't change out from under us.
|
| - std::set<PepperPluginInstanceImpl*> plugins = active_instances_;
|
| - for (std::set<PepperPluginInstanceImpl*>::iterator i = plugins.begin();
|
| - i != plugins.end(); ++i) {
|
| - // The copy above makes sure our iterator is never invalid if some plugins
|
| - // are destroyed. But some plugin may decide to close all of its views in
|
| - // response to a paint in one of them, so we need to make sure each one is
|
| - // still "current" before using it.
|
| - //
|
| - // It's possible that a plugin was destroyed, but another one was created
|
| - // with the same address. In this case, we'll call ViewFlushedPaint on that
|
| - // new plugin. But that's OK for this particular case since we're just
|
| - // notifying all of our instances that the view flushed, and the new one is
|
| - // one of our instances.
|
| - //
|
| - // What about the case where a new one is created in a callback at a new
|
| - // address and we don't issue the callback? We're still OK since this
|
| - // callback is used for flush callbacks and we could not have possibly
|
| - // started a new paint (ViewWillInitiatePaint) for the new plugin while
|
| - // processing a previous paint for an existing one.
|
| - if (active_instances_.find(*i) != active_instances_.end())
|
| - (*i)->ViewFlushedPaint();
|
| - }
|
| -}
|
| -
|
| -PepperPluginInstanceImpl* PepperPluginDelegateImpl::
|
| - GetBitmapForOptimizedPluginPaint(
|
| - const gfx::Rect& paint_bounds,
|
| - TransportDIB** dib,
|
| - gfx::Rect* location,
|
| - gfx::Rect* clip,
|
| - float* scale_factor) {
|
| - for (std::set<PepperPluginInstanceImpl*>::iterator i =
|
| - active_instances_.begin();
|
| - i != active_instances_.end(); ++i) {
|
| - PepperPluginInstanceImpl* instance = *i;
|
| - // In Flash fullscreen , the plugin contents should be painted onto the
|
| - // fullscreen widget instead of the web page.
|
| - if (!instance->FlashIsFullscreenOrPending() &&
|
| - instance->GetBitmapForOptimizedPluginPaint(paint_bounds, dib, location,
|
| - clip, scale_factor))
|
| - return *i;
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::PluginFocusChanged(
|
| - PepperPluginInstanceImpl* instance,
|
| - bool focused) {
|
| - if (focused)
|
| - focused_plugin_ = instance;
|
| - else if (focused_plugin_ == instance)
|
| - focused_plugin_ = NULL;
|
| - if (render_view_)
|
| - render_view_->PpapiPluginFocusChanged();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::PluginTextInputTypeChanged(
|
| - PepperPluginInstanceImpl* instance) {
|
| - if (focused_plugin_ == instance && render_view_)
|
| - render_view_->PpapiPluginTextInputTypeChanged();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::PluginCaretPositionChanged(
|
| - PepperPluginInstanceImpl* instance) {
|
| - if (focused_plugin_ == instance && render_view_)
|
| - render_view_->PpapiPluginCaretPositionChanged();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::PluginRequestedCancelComposition(
|
| - PepperPluginInstanceImpl* instance) {
|
| - if (focused_plugin_ == instance && render_view_)
|
| - render_view_->PpapiPluginCancelComposition();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::PluginSelectionChanged(
|
| - PepperPluginInstanceImpl* instance) {
|
| - if (focused_plugin_ == instance && render_view_)
|
| - render_view_->PpapiPluginSelectionChanged();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnImeSetComposition(
|
| - const string16& text,
|
| - const std::vector<WebKit::WebCompositionUnderline>& underlines,
|
| - int selection_start,
|
| - int selection_end) {
|
| - if (!IsPluginAcceptingCompositionEvents()) {
|
| - composition_text_ = text;
|
| - } else {
|
| - // TODO(kinaba) currently all composition events are sent directly to
|
| - // plugins. Use DOM event mechanism after WebKit is made aware about
|
| - // plugins that support composition.
|
| - // The code below mimics the behavior of WebCore::Editor::setComposition.
|
| -
|
| - // Empty -> nonempty: composition started.
|
| - if (composition_text_.empty() && !text.empty())
|
| - focused_plugin_->HandleCompositionStart(string16());
|
| - // Nonempty -> empty: composition canceled.
|
| - if (!composition_text_.empty() && text.empty())
|
| - focused_plugin_->HandleCompositionEnd(string16());
|
| - composition_text_ = text;
|
| - // Nonempty: composition is ongoing.
|
| - if (!composition_text_.empty()) {
|
| - focused_plugin_->HandleCompositionUpdate(composition_text_, underlines,
|
| - selection_start, selection_end);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnImeConfirmComposition(const string16& text) {
|
| - // Here, text.empty() has a special meaning. It means to commit the last
|
| - // update of composition text (see RenderWidgetHost::ImeConfirmComposition()).
|
| - const string16& last_text = text.empty() ? composition_text_ : text;
|
| -
|
| - // last_text is empty only when both text and composition_text_ is. Ignore it.
|
| - if (last_text.empty())
|
| - return;
|
| -
|
| - if (!IsPluginAcceptingCompositionEvents()) {
|
| - for (size_t i = 0; i < text.size(); ++i) {
|
| - WebKit::WebKeyboardEvent char_event;
|
| - char_event.type = WebKit::WebInputEvent::Char;
|
| - char_event.timeStampSeconds = base::Time::Now().ToDoubleT();
|
| - char_event.modifiers = 0;
|
| - char_event.windowsKeyCode = last_text[i];
|
| - char_event.nativeKeyCode = last_text[i];
|
| - char_event.text[0] = last_text[i];
|
| - char_event.unmodifiedText[0] = last_text[i];
|
| - if (render_view_->webwidget())
|
| - render_view_->webwidget()->handleInputEvent(char_event);
|
| - }
|
| - } else {
|
| - // Mimics the order of events sent by WebKit.
|
| - // See WebCore::Editor::setComposition() for the corresponding code.
|
| - focused_plugin_->HandleCompositionEnd(last_text);
|
| - focused_plugin_->HandleTextInput(last_text);
|
| - }
|
| - composition_text_.clear();
|
| -}
|
| -
|
| -gfx::Rect PepperPluginDelegateImpl::GetCaretBounds() const {
|
| - if (!focused_plugin_)
|
| - return gfx::Rect(0, 0, 0, 0);
|
| - return focused_plugin_->GetCaretBounds();
|
| -}
|
| -
|
| -ui::TextInputType PepperPluginDelegateImpl::GetTextInputType() const {
|
| - if (!focused_plugin_)
|
| - return ui::TEXT_INPUT_TYPE_NONE;
|
| - return focused_plugin_->text_input_type();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::GetSurroundingText(string16* text,
|
| - ui::Range* range) const {
|
| - if (!focused_plugin_)
|
| - return;
|
| - return focused_plugin_->GetSurroundingText(text, range);
|
| -}
|
| -
|
| -bool PepperPluginDelegateImpl::IsPluginAcceptingCompositionEvents() const {
|
| - if (!focused_plugin_)
|
| - return false;
|
| - return focused_plugin_->IsPluginAcceptingCompositionEvents();
|
| -}
|
| -
|
| -bool PepperPluginDelegateImpl::CanComposeInline() const {
|
| - return IsPluginAcceptingCompositionEvents();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::InstanceCreated(
|
| - PepperPluginInstanceImpl* instance) {
|
| - active_instances_.insert(instance);
|
| -
|
| - // Set the initial focus.
|
| - instance->SetContentAreaFocus(render_view_->has_focus());
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::InstanceDeleted(
|
| - PepperPluginInstanceImpl* instance) {
|
| - active_instances_.erase(instance);
|
| -
|
| - if (last_mouse_event_target_ == instance)
|
| - last_mouse_event_target_ = NULL;
|
| - if (focused_plugin_ == instance)
|
| - PluginFocusChanged(instance, false);
|
| -}
|
| -
|
| -// If a broker has not already been created for this plugin, creates one.
|
| -PepperBroker* PepperPluginDelegateImpl::ConnectToBroker(
|
| - PPB_Broker_Impl* client) {
|
| - DCHECK(client);
|
| -
|
| - PluginModule* plugin_module = ResourceHelper::GetPluginModule(client);
|
| - if (!plugin_module)
|
| - return NULL;
|
| -
|
| - scoped_refptr<PepperBroker> broker =
|
| - static_cast<PepperBroker*>(plugin_module->GetBroker());
|
| - if (!broker.get())
|
| - broker = CreateBroker(plugin_module);
|
| -
|
| - int request_id = pending_permission_requests_.Add(
|
| - new base::WeakPtr<PPB_Broker_Impl>(client->AsWeakPtr()));
|
| - Send(new ViewHostMsg_RequestPpapiBrokerPermission(
|
| - routing_id(),
|
| - request_id,
|
| - client->GetDocumentUrl(),
|
| - plugin_module->path()));
|
| -
|
| - // Adds a reference, ensuring that the broker is not deleted when
|
| - // |broker| goes out of scope.
|
| - broker->AddPendingConnect(client);
|
| -
|
| - return broker.get();
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnPpapiBrokerPermissionResult(
|
| - int request_id,
|
| - bool result) {
|
| - scoped_ptr<base::WeakPtr<PPB_Broker_Impl> > client_ptr(
|
| - pending_permission_requests_.Lookup(request_id));
|
| - DCHECK(client_ptr.get());
|
| - pending_permission_requests_.Remove(request_id);
|
| - base::WeakPtr<PPB_Broker_Impl> client = *client_ptr;
|
| - if (!client.get())
|
| - return;
|
| -
|
| - PluginModule* plugin_module = ResourceHelper::GetPluginModule(client.get());
|
| - if (!plugin_module)
|
| - return;
|
| -
|
| - PepperBroker* broker = static_cast<PepperBroker*>(plugin_module->GetBroker());
|
| - broker->OnBrokerPermissionResult(client.get(), result);
|
| -}
|
| -
|
| -bool PepperPluginDelegateImpl::AsyncOpenFile(
|
| - const base::FilePath& path,
|
| - int flags,
|
| - const AsyncOpenFileCallback& callback) {
|
| - int message_id = pending_async_open_files_.Add(
|
| - new AsyncOpenFileCallback(callback));
|
| - return Send(new ViewHostMsg_AsyncOpenFile(
|
| - routing_id(), path, flags, message_id));
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnAsyncFileOpened(
|
| - base::PlatformFileError error_code,
|
| - IPC::PlatformFileForTransit file_for_transit,
|
| - int message_id) {
|
| - AsyncOpenFileCallback* callback =
|
| - pending_async_open_files_.Lookup(message_id);
|
| - DCHECK(callback);
|
| - pending_async_open_files_.Remove(message_id);
|
| -
|
| - base::PlatformFile file =
|
| - IPC::PlatformFileForTransitToPlatformFile(file_for_transit);
|
| - callback->Run(error_code, base::PassPlatformFile(&file));
|
| - // Make sure we won't leak file handle if the requester has died.
|
| - if (file != base::kInvalidPlatformFileValue) {
|
| - base::FileUtilProxy::Close(
|
| - RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
|
| - file,
|
| - base::FileUtilProxy::StatusCallback());
|
| - }
|
| - delete callback;
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnSetFocus(bool has_focus) {
|
| - for (std::set<PepperPluginInstanceImpl*>::iterator i =
|
| - active_instances_.begin();
|
| - i != active_instances_.end(); ++i)
|
| - (*i)->SetContentAreaFocus(has_focus);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::PageVisibilityChanged(bool is_visible) {
|
| - for (std::set<PepperPluginInstanceImpl*>::iterator i =
|
| - active_instances_.begin();
|
| - i != active_instances_.end(); ++i)
|
| - (*i)->PageVisibilityChanged(is_visible);
|
| -}
|
| -
|
| -bool PepperPluginDelegateImpl::IsPluginFocused() const {
|
| - return focused_plugin_ != NULL;
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::WillHandleMouseEvent() {
|
| - // This method is called for every mouse event that the render view receives.
|
| - // And then the mouse event is forwarded to WebKit, which dispatches it to the
|
| - // event target. Potentially a Pepper plugin will receive the event.
|
| - // In order to tell whether a plugin gets the last mouse event and which it
|
| - // is, we set |last_mouse_event_target_| to NULL here. If a plugin gets the
|
| - // event, it will notify us via DidReceiveMouseEvent() and set itself as
|
| - // |last_mouse_event_target_|.
|
| - last_mouse_event_target_ = NULL;
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::RegisterTCPSocket(
|
| - PPB_TCPSocket_Private_Impl* socket,
|
| - uint32 socket_id) {
|
| - tcp_sockets_.AddWithID(socket, socket_id);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::UnregisterTCPSocket(uint32 socket_id) {
|
| - // There is no DCHECK(tcp_sockets_.Lookup(socket_id)) because this method
|
| - // can be called before TCPSocketConnect or TCPSocketConnectWithNetAddress.
|
| - if (tcp_sockets_.Lookup(socket_id))
|
| - tcp_sockets_.Remove(socket_id);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::TCPServerSocketStopListening(uint32 socket_id) {
|
| - tcp_server_sockets_.Remove(socket_id);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::HandleDocumentLoad(
|
| - PepperPluginInstanceImpl* instance,
|
| - const WebKit::WebURLResponse& response) {
|
| - DCHECK(!instance->document_loader());
|
| -
|
| - PP_Instance pp_instance = instance->pp_instance();
|
| - RendererPpapiHostImpl* host_impl = instance->module()->renderer_ppapi_host();
|
| -
|
| - // Create a loader resource host for this load. Note that we have to set
|
| - // the document_loader before issuing the in-process
|
| - // PPP_Instance.HandleDocumentLoad call below, since this may reentrantly
|
| - // call into the instance and expect it to be valid.
|
| - PepperURLLoaderHost* loader_host =
|
| - new PepperURLLoaderHost(host_impl, true, pp_instance, 0);
|
| - instance->set_document_loader(loader_host);
|
| - loader_host->didReceiveResponse(NULL, response);
|
| -
|
| - // This host will be pending until the resource object attaches to it.
|
| - int pending_host_id = host_impl->GetPpapiHost()->AddPendingResourceHost(
|
| - scoped_ptr<ppapi::host::ResourceHost>(loader_host));
|
| - DCHECK(pending_host_id);
|
| - ppapi::URLResponseInfoData data =
|
| - DataFromWebURLResponse(pp_instance, response);
|
| -
|
| - if (host_impl->in_process_router()) {
|
| - // Running in-process, we can just create the resource and call the
|
| - // PPP_Instance function directly.
|
| - scoped_refptr<ppapi::proxy::URLLoaderResource> loader_resource(
|
| - new ppapi::proxy::URLLoaderResource(
|
| - host_impl->in_process_router()->GetPluginConnection(pp_instance),
|
| - pp_instance, pending_host_id, data));
|
| -
|
| - PP_Resource loader_pp_resource = loader_resource->GetReference();
|
| - if (!instance->instance_interface()->HandleDocumentLoad(
|
| - instance->pp_instance(), loader_pp_resource))
|
| - loader_resource->Close();
|
| - // We don't pass a ref into the plugin, if it wants one, it will have taken
|
| - // an additional one.
|
| - ppapi::PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(
|
| - loader_pp_resource);
|
| -
|
| - // Danger! If the plugin doesn't take a ref in HandleDocumentLoad, the
|
| - // resource host will be destroyed as soon as our scoped_refptr for the
|
| - // resource goes out of scope.
|
| - //
|
| - // Null it out so people don't accidentally add code below that uses it.
|
| - loader_host = NULL;
|
| - } else {
|
| - // Running out-of-process. Initiate an IPC call to notify the plugin
|
| - // process.
|
| - ppapi::proxy::HostDispatcher* dispatcher =
|
| - ppapi::proxy::HostDispatcher::GetForInstance(pp_instance);
|
| - dispatcher->Send(new PpapiMsg_PPPInstance_HandleDocumentLoad(
|
| - ppapi::API_ID_PPP_INSTANCE, pp_instance, pending_host_id, data));
|
| - }
|
| -}
|
| -
|
| -RendererPpapiHost* PepperPluginDelegateImpl::CreateExternalPluginModule(
|
| - scoped_refptr<PluginModule> module,
|
| - const base::FilePath& path,
|
| - ppapi::PpapiPermissions permissions,
|
| - const IPC::ChannelHandle& channel_handle,
|
| - base::ProcessId peer_pid,
|
| - int plugin_child_id) {
|
| - // We don't call PepperPluginRegistry::AddLiveModule, as this module is
|
| - // managed externally.
|
| - return CreateOutOfProcessModule(module.get(),
|
| - path,
|
| - permissions,
|
| - channel_handle,
|
| - peer_pid,
|
| - plugin_child_id,
|
| - true); // is_external = true
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::DidChangeCursor(
|
| - PepperPluginInstanceImpl* instance,
|
| - const WebKit::WebCursorInfo& cursor) {
|
| - // Update the cursor appearance immediately if the requesting plugin is the
|
| - // one which receives the last mouse event. Otherwise, the new cursor won't be
|
| - // picked up until the plugin gets the next input event. That is bad if, e.g.,
|
| - // the plugin would like to set an invisible cursor when there isn't any user
|
| - // input for a while.
|
| - if (instance == last_mouse_event_target_)
|
| - render_view_->didChangeCursor(cursor);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::DidReceiveMouseEvent(
|
| - PepperPluginInstanceImpl* instance) {
|
| - last_mouse_event_target_ = instance;
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::SampleGamepads(WebKit::WebGamepads* data) {
|
| - if (!gamepad_shared_memory_reader_)
|
| - gamepad_shared_memory_reader_.reset(new GamepadSharedMemoryReader);
|
| - gamepad_shared_memory_reader_->SampleGamepads(*data);
|
| -}
|
| -
|
| -bool PepperPluginDelegateImpl::OnMessageReceived(const IPC::Message& message) {
|
| - if (pepper_browser_connection_.OnMessageReceived(message))
|
| - return true;
|
| -
|
| - bool handled = true;
|
| - IPC_BEGIN_MESSAGE_MAP(PepperPluginDelegateImpl, message)
|
| - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ConnectACK,
|
| - OnTCPSocketConnectACK)
|
| - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SSLHandshakeACK,
|
| - OnTCPSocketSSLHandshakeACK)
|
| - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnTCPSocketReadACK)
|
| - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnTCPSocketWriteACK)
|
| - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK,
|
| - OnTCPSocketSetOptionACK)
|
| - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_ListenACK,
|
| - OnTCPServerSocketListenACK)
|
| - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_AcceptACK,
|
| - OnTCPServerSocketAcceptACK)
|
| - IPC_MESSAGE_HANDLER(ViewMsg_PpapiBrokerChannelCreated,
|
| - OnPpapiBrokerChannelCreated)
|
| - IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenFile_ACK, OnAsyncFileOpened)
|
| - IPC_MESSAGE_HANDLER(ViewMsg_PpapiBrokerPermissionResult,
|
| - OnPpapiBrokerPermissionResult)
|
| - IPC_MESSAGE_UNHANDLED(handled = false)
|
| - IPC_END_MESSAGE_MAP()
|
| - return handled;
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnDestruct() {
|
| - // Nothing to do here. Default implementation in RenderViewObserver does
|
| - // 'delete this' but it's not suitable for PepperPluginDelegateImpl because
|
| - // it's non-pointer member in RenderViewImpl.
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnTCPSocketConnectACK(
|
| - uint32 plugin_dispatcher_id,
|
| - uint32 socket_id,
|
| - int32_t result,
|
| - const PP_NetAddress_Private& local_addr,
|
| - const PP_NetAddress_Private& remote_addr) {
|
| - PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id);
|
| - if (socket)
|
| - socket->OnConnectCompleted(result, local_addr, remote_addr);
|
| - if (result != PP_OK)
|
| - tcp_sockets_.Remove(socket_id);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnTCPSocketSSLHandshakeACK(
|
| - uint32 plugin_dispatcher_id,
|
| - uint32 socket_id,
|
| - bool succeeded,
|
| - const ppapi::PPB_X509Certificate_Fields& certificate_fields) {
|
| - PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id);
|
| - if (socket)
|
| - socket->OnSSLHandshakeCompleted(succeeded, certificate_fields);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnTCPSocketReadACK(uint32 plugin_dispatcher_id,
|
| - uint32 socket_id,
|
| - int32_t result,
|
| - const std::string& data) {
|
| - PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id);
|
| - if (socket)
|
| - socket->OnReadCompleted(result, data);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnTCPSocketWriteACK(uint32 plugin_dispatcher_id,
|
| - uint32 socket_id,
|
| - int32_t result) {
|
| - PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id);
|
| - if (socket)
|
| - socket->OnWriteCompleted(result);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnTCPSocketSetOptionACK(
|
| - uint32 plugin_dispatcher_id,
|
| - uint32 socket_id,
|
| - int32_t result) {
|
| - PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id);
|
| - if (socket)
|
| - socket->OnSetOptionCompleted(result);
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnTCPServerSocketListenACK(
|
| - uint32 plugin_dispatcher_id,
|
| - PP_Resource socket_resource,
|
| - uint32 socket_id,
|
| - const PP_NetAddress_Private& local_addr,
|
| - int32_t status) {
|
| - ppapi::thunk::EnterResource<ppapi::thunk::PPB_TCPServerSocket_Private_API>
|
| - enter(socket_resource, true);
|
| - if (enter.succeeded()) {
|
| - ppapi::PPB_TCPServerSocket_Shared* socket =
|
| - static_cast<ppapi::PPB_TCPServerSocket_Shared*>(enter.object());
|
| - if (status == PP_OK)
|
| - tcp_server_sockets_.AddWithID(socket, socket_id);
|
| - socket->OnListenCompleted(socket_id, local_addr, status);
|
| - } else if (socket_id != 0 && status == PP_OK) {
|
| - // StopListening was called before completion of Listen.
|
| - Send(new PpapiHostMsg_PPBTCPServerSocket_Destroy(socket_id));
|
| - }
|
| -}
|
| -
|
| -void PepperPluginDelegateImpl::OnTCPServerSocketAcceptACK(
|
| - uint32 plugin_dispatcher_id,
|
| - uint32 server_socket_id,
|
| - uint32 accepted_socket_id,
|
| - const PP_NetAddress_Private& local_addr,
|
| - const PP_NetAddress_Private& remote_addr) {
|
| - ppapi::PPB_TCPServerSocket_Shared* socket =
|
| - tcp_server_sockets_.Lookup(server_socket_id);
|
| - if (socket) {
|
| - bool succeeded = (accepted_socket_id != 0);
|
| - socket->OnAcceptCompleted(succeeded,
|
| - accepted_socket_id,
|
| - local_addr,
|
| - remote_addr);
|
| - } else if (accepted_socket_id != 0) {
|
| - Send(new PpapiHostMsg_PPBTCPSocket_Disconnect(accepted_socket_id));
|
| - }
|
| -}
|
| -
|
| -} // namespace content
|
|
|