summaryrefslogtreecommitdiffstats
path: root/chrome/plugin/plugin_channel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/plugin/plugin_channel.cc')
-rw-r--r--chrome/plugin/plugin_channel.cc328
1 files changed, 0 insertions, 328 deletions
diff --git a/chrome/plugin/plugin_channel.cc b/chrome/plugin/plugin_channel.cc
deleted file mode 100644
index 10151ad..0000000
--- a/chrome/plugin/plugin_channel.cc
+++ /dev/null
@@ -1,328 +0,0 @@
-// Copyright (c) 2010 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 "chrome/plugin/plugin_channel.h"
-
-#include "base/command_line.h"
-#include "base/process_util.h"
-#include "base/string_util.h"
-#include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
-#include "build/build_config.h"
-#include "chrome/plugin/plugin_thread.h"
-#include "chrome/plugin/webplugin_delegate_stub.h"
-#include "chrome/plugin/webplugin_proxy.h"
-#include "content/common/child_process.h"
-#include "content/common/content_switches.h"
-#include "content/common/plugin_messages.h"
-#include "webkit/plugins/npapi/plugin_instance.h"
-
-#if defined(OS_POSIX)
-#include "base/eintr_wrapper.h"
-#include "ipc/ipc_channel_posix.h"
-#endif
-
-namespace {
-
-class PluginReleaseTask : public Task {
- public:
- void Run() {
- ChildProcess::current()->ReleaseProcess();
- }
-};
-
-// How long we wait before releasing the plugin process.
-const int kPluginReleaseTimeMs = 5 * 60 * 1000; // 5 minutes
-
-} // namespace
-
-// If a sync call to the renderer results in a modal dialog, we need to have a
-// way to know so that we can run a nested message loop to simulate what would
-// happen in a single process browser and avoid deadlock.
-class PluginChannel::MessageFilter : public IPC::ChannelProxy::MessageFilter {
- public:
- MessageFilter() : channel_(NULL) { }
- ~MessageFilter() {
- // Clean up in case of renderer crash.
- for (ModalDialogEventMap::iterator i = modal_dialog_event_map_.begin();
- i != modal_dialog_event_map_.end(); ++i) {
- delete i->second.event;
- }
- }
-
- base::WaitableEvent* GetModalDialogEvent(
- gfx::NativeViewId containing_window) {
- base::AutoLock auto_lock(modal_dialog_event_map_lock_);
- if (!modal_dialog_event_map_.count(containing_window)) {
- NOTREACHED();
- return NULL;
- }
-
- return modal_dialog_event_map_[containing_window].event;
- }
-
- // Decrement the ref count associated with the modal dialog event for the
- // given tab.
- void ReleaseModalDialogEvent(gfx::NativeViewId containing_window) {
- base::AutoLock auto_lock(modal_dialog_event_map_lock_);
- if (!modal_dialog_event_map_.count(containing_window)) {
- NOTREACHED();
- return;
- }
-
- if (--(modal_dialog_event_map_[containing_window].refcount))
- return;
-
- // Delete the event when the stack unwinds as it could be in use now.
- MessageLoop::current()->DeleteSoon(
- FROM_HERE, modal_dialog_event_map_[containing_window].event);
- modal_dialog_event_map_.erase(containing_window);
- }
-
- bool Send(IPC::Message* message) {
- // Need this function for the IPC_MESSAGE_HANDLER_DELAY_REPLY macro.
- return channel_->Send(message);
- }
-
- private:
- void OnFilterAdded(IPC::Channel* channel) { channel_ = channel; }
-
- bool OnMessageReceived(const IPC::Message& message) {
- IPC_BEGIN_MESSAGE_MAP(PluginChannel::MessageFilter, message)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_Init, OnInit)
- IPC_MESSAGE_HANDLER(PluginMsg_SignalModalDialogEvent,
- OnSignalModalDialogEvent)
- IPC_MESSAGE_HANDLER(PluginMsg_ResetModalDialogEvent,
- OnResetModalDialogEvent)
- IPC_END_MESSAGE_MAP()
- return message.type() == PluginMsg_SignalModalDialogEvent::ID ||
- message.type() == PluginMsg_ResetModalDialogEvent::ID;
- }
-
- void OnInit(const PluginMsg_Init_Params& params, IPC::Message* reply_msg) {
- base::AutoLock auto_lock(modal_dialog_event_map_lock_);
- if (modal_dialog_event_map_.count(params.containing_window)) {
- modal_dialog_event_map_[params.containing_window].refcount++;
- return;
- }
-
- WaitableEventWrapper wrapper;
- wrapper.event = new base::WaitableEvent(true, false);
- wrapper.refcount = 1;
- modal_dialog_event_map_[params.containing_window] = wrapper;
- }
-
- void OnSignalModalDialogEvent(gfx::NativeViewId containing_window) {
- base::AutoLock auto_lock(modal_dialog_event_map_lock_);
- if (modal_dialog_event_map_.count(containing_window))
- modal_dialog_event_map_[containing_window].event->Signal();
- }
-
- void OnResetModalDialogEvent(gfx::NativeViewId containing_window) {
- base::AutoLock auto_lock(modal_dialog_event_map_lock_);
- if (modal_dialog_event_map_.count(containing_window))
- modal_dialog_event_map_[containing_window].event->Reset();
- }
-
- struct WaitableEventWrapper {
- base::WaitableEvent* event;
- int refcount; // There could be multiple plugin instances per tab.
- };
- typedef std::map<gfx::NativeViewId, WaitableEventWrapper> ModalDialogEventMap;
- ModalDialogEventMap modal_dialog_event_map_;
- base::Lock modal_dialog_event_map_lock_;
-
- IPC::Channel* channel_;
-};
-
-PluginChannel* PluginChannel::GetPluginChannel(int renderer_id,
- MessageLoop* ipc_message_loop) {
- // Map renderer ID to a (single) channel to that process.
- std::string channel_key = StringPrintf(
- "%d.r%d", base::GetCurrentProcId(), renderer_id);
-
- PluginChannel* channel =
- static_cast<PluginChannel*>(PluginChannelBase::GetChannel(
- channel_key,
- IPC::Channel::MODE_SERVER,
- ClassFactory,
- ipc_message_loop,
- false));
-
- if (channel)
- channel->renderer_id_ = renderer_id;
-
- return channel;
-}
-
-// static
-void PluginChannel::NotifyRenderersOfPendingShutdown() {
- Broadcast(new PluginHostMsg_PluginShuttingDown());
-}
-
-PluginChannel::PluginChannel()
- : renderer_handle_(0),
- renderer_id_(-1),
- in_send_(0),
- incognito_(false),
- filter_(new MessageFilter()) {
- set_send_unblocking_only_during_unblock_dispatch();
- ChildProcess::current()->AddRefProcess();
- const CommandLine* command_line = CommandLine::ForCurrentProcess();
- log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
-}
-
-PluginChannel::~PluginChannel() {
- if (renderer_handle_)
- base::CloseProcessHandle(renderer_handle_);
-
- MessageLoop::current()->PostDelayedTask(FROM_HERE, new PluginReleaseTask(),
- kPluginReleaseTimeMs);
-}
-
-bool PluginChannel::Send(IPC::Message* msg) {
- in_send_++;
- if (log_messages_) {
- VLOG(1) << "sending message @" << msg << " on channel @" << this
- << " with type " << msg->type();
- }
- bool result = PluginChannelBase::Send(msg);
- in_send_--;
- return result;
-}
-
-bool PluginChannel::OnMessageReceived(const IPC::Message& msg) {
- if (log_messages_) {
- VLOG(1) << "received message @" << &msg << " on channel @" << this
- << " with type " << msg.type();
- }
- return PluginChannelBase::OnMessageReceived(msg);
-}
-
-bool PluginChannel::OnControlMessageReceived(const IPC::Message& msg) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(PluginChannel, msg)
- IPC_MESSAGE_HANDLER(PluginMsg_CreateInstance, OnCreateInstance)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_DestroyInstance,
- OnDestroyInstance)
- IPC_MESSAGE_HANDLER(PluginMsg_GenerateRouteID, OnGenerateRouteID)
- IPC_MESSAGE_HANDLER(PluginMsg_ClearSiteData, OnClearSiteData)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- DCHECK(handled);
- return handled;
-}
-
-void PluginChannel::OnCreateInstance(const std::string& mime_type,
- int* instance_id) {
- *instance_id = GenerateRouteID();
- scoped_refptr<WebPluginDelegateStub> stub(new WebPluginDelegateStub(
- mime_type, *instance_id, this));
- AddRoute(*instance_id, stub, NULL);
- plugin_stubs_.push_back(stub);
-}
-
-void PluginChannel::OnDestroyInstance(int instance_id,
- IPC::Message* reply_msg) {
- for (size_t i = 0; i < plugin_stubs_.size(); ++i) {
- if (plugin_stubs_[i]->instance_id() == instance_id) {
- scoped_refptr<MessageFilter> filter(filter_);
- gfx::NativeViewId window =
- plugin_stubs_[i]->webplugin()->containing_window();
- plugin_stubs_.erase(plugin_stubs_.begin() + i);
- Send(reply_msg);
- RemoveRoute(instance_id);
- // NOTE: *this* might be deleted as a result of calling RemoveRoute.
- // Don't release the modal dialog event right away, but do it after the
- // stack unwinds since the plugin can be destroyed later if it's in use
- // right now.
- MessageLoop::current()->PostNonNestableTask(FROM_HERE, NewRunnableMethod(
- filter.get(), &MessageFilter::ReleaseModalDialogEvent, window));
- return;
- }
- }
-
- NOTREACHED() << "Couldn't find WebPluginDelegateStub to destroy";
-}
-
-void PluginChannel::OnGenerateRouteID(int* route_id) {
- *route_id = GenerateRouteID();
-}
-
-int PluginChannel::GenerateRouteID() {
- static int last_id = 0;
- return ++last_id;
-}
-
-void PluginChannel::OnClearSiteData(const std::string& site,
- uint64 flags,
- base::Time begin_time) {
- bool success = false;
- CommandLine* command_line = CommandLine::ForCurrentProcess();
- FilePath path = command_line->GetSwitchValuePath(switches::kPluginPath);
- scoped_refptr<webkit::npapi::PluginLib> plugin_lib(
- webkit::npapi::PluginLib::CreatePluginLib(path));
- if (plugin_lib.get()) {
- NPError err = plugin_lib->NP_Initialize();
- if (err == NPERR_NO_ERROR) {
- const char* site_str = site.empty() ? NULL : site.c_str();
- uint64 max_age;
- if (begin_time > base::Time()) {
- base::TimeDelta delta = base::Time::Now() - begin_time;
- max_age = delta.InSeconds();
- } else {
- max_age = kuint64max;
- }
- err = plugin_lib->NP_ClearSiteData(site_str, flags, max_age);
- success = (err == NPERR_NO_ERROR);
- }
- }
- Send(new PluginHostMsg_ClearSiteDataResult(success));
-}
-
-base::WaitableEvent* PluginChannel::GetModalDialogEvent(
- gfx::NativeViewId containing_window) {
- return filter_->GetModalDialogEvent(containing_window);
-}
-
-void PluginChannel::OnChannelConnected(int32 peer_pid) {
- base::ProcessHandle handle;
- if (!base::OpenProcessHandle(peer_pid, &handle)) {
- NOTREACHED();
- }
- renderer_handle_ = handle;
- PluginChannelBase::OnChannelConnected(peer_pid);
-}
-
-void PluginChannel::OnChannelError() {
- base::CloseProcessHandle(renderer_handle_);
- renderer_handle_ = 0;
- PluginChannelBase::OnChannelError();
- CleanUp();
-}
-
-void PluginChannel::CleanUp() {
- // We need to clean up the stubs so that they call NPPDestroy. This will
- // also lead to them releasing their reference on this object so that it can
- // be deleted.
- for (size_t i = 0; i < plugin_stubs_.size(); ++i)
- RemoveRoute(plugin_stubs_[i]->instance_id());
-
- // Need to addref this object temporarily because otherwise removing the last
- // stub will cause the destructor of this object to be called, however at
- // that point plugin_stubs_ will have one element and its destructor will be
- // called twice.
- scoped_refptr<PluginChannel> me(this);
-
- plugin_stubs_.clear();
-}
-
-bool PluginChannel::Init(MessageLoop* ipc_message_loop, bool create_pipe_now) {
- if (!PluginChannelBase::Init(ipc_message_loop, create_pipe_now))
- return false;
-
- channel_->AddFilter(filter_.get());
- return true;
-}
-