diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-18 13:26:40 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-18 13:26:40 +0000 |
commit | 8b8a554df8a76731fc1b7aa74826ac729ba6980d (patch) | |
tree | a082c4de6beece2944c10d40a94bef317fb3f3cc /chrome | |
parent | 9f43551bf8c197bf716530a4d26a368a3cc5e0b3 (diff) | |
download | chromium_src-8b8a554df8a76731fc1b7aa74826ac729ba6980d.zip chromium_src-8b8a554df8a76731fc1b7aa74826ac729ba6980d.tar.gz chromium_src-8b8a554df8a76731fc1b7aa74826ac729ba6980d.tar.bz2 |
Add PluginDataRemover.
BUG=58235
TEST=none
Review URL: http://codereview.chromium.org/4832002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66615 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/plugin_data_remover.cc | 118 | ||||
-rw-r--r-- | chrome/browser/plugin_data_remover.h | 57 | ||||
-rw-r--r-- | chrome/browser/plugin_service.cc | 20 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/common/plugin_messages_internal.h | 8 | ||||
-rw-r--r-- | chrome/plugin/plugin_channel.cc | 31 | ||||
-rw-r--r-- | chrome/plugin/plugin_channel.h | 3 |
7 files changed, 226 insertions, 13 deletions
diff --git a/chrome/browser/plugin_data_remover.cc b/chrome/browser/plugin_data_remover.cc new file mode 100644 index 0000000..4415c5f --- /dev/null +++ b/chrome/browser/plugin_data_remover.cc @@ -0,0 +1,118 @@ +// 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/browser/plugin_data_remover.h" + +#include "base/message_loop_proxy.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/browser/plugin_service.h" +#include "chrome/common/plugin_messages.h" +#include "ipc/ipc_channel.h" + +#if defined(OS_POSIX) +#include "ipc/ipc_channel_posix.h" +#endif + +namespace { +const std::string flash_mime_type = "application/x-shockwave-flash"; +const int64 timeout_ms = 10000; +} + +PluginDataRemover::PluginDataRemover() + : channel_(NULL), + method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { +} + +PluginDataRemover::~PluginDataRemover() { + DCHECK(!done_task_.get()); + if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_)) + delete channel_; +} + +void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) { + DCHECK(!done_task_.get()); + begin_time_ = begin_time; + + message_loop_ = base::MessageLoopProxy::CreateForCurrentThread(); + done_task_.reset(done_task); + + PluginService::GetInstance()->OpenChannelToPlugin( + GURL(), flash_mime_type, this); + + BrowserThread::PostDelayedTask( + BrowserThread::IO, + FROM_HERE, + method_factory_.NewRunnableMethod(&PluginDataRemover::OnTimeout), + timeout_ms); +} + +int PluginDataRemover::ID() { + // Generate an ID for the browser process. + return ChildProcessInfo::GenerateChildProcessUniqueId(); +} + +bool PluginDataRemover::OffTheRecord() { + return false; +} + +void PluginDataRemover::SetPluginInfo(const WebPluginInfo& info) { +} + +void PluginDataRemover::OnChannelOpened(const IPC::ChannelHandle& handle) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(!channel_); +#if defined(OS_POSIX) + // If we received a ChannelHandle, register it now. + if (handle.socket.fd >= 0) + IPC::AddChannelSocket(handle.name, handle.socket.fd); +#endif + channel_ = new IPC::Channel(handle.name, IPC::Channel::MODE_CLIENT, this); + if (!channel_->Connect()) { + NOTREACHED() << "Couldn't connect to plugin"; + SignalDone(); + return; + } + + if (!channel_->Send( + new PluginMsg_ClearSiteData(0, std::string(), begin_time_))) { + NOTREACHED() << "Couldn't send ClearSiteData message"; + SignalDone(); + } +} + +void PluginDataRemover::OnError() { + NOTREACHED() << "Couldn't open plugin channel"; + SignalDone(); +} + +void PluginDataRemover::OnClearSiteDataResult(bool success) { + DCHECK(success) << "ClearSiteData returned error"; + SignalDone(); +} + +void PluginDataRemover::OnTimeout() { + NOTREACHED() << "Timed out"; + SignalDone(); +} + +void PluginDataRemover::OnMessageReceived(const IPC::Message& msg) { + IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg) + IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, + OnClearSiteDataResult) + IPC_MESSAGE_UNHANDLED_ERROR() + IPC_END_MESSAGE_MAP() +} + +void PluginDataRemover::OnChannelError() { + NOTREACHED() << "Channel error"; + SignalDone(); +} + +void PluginDataRemover::SignalDone() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (!done_task_.get()) + return; + message_loop_->PostTask(FROM_HERE, done_task_.release()); + message_loop_ = NULL; +} diff --git a/chrome/browser/plugin_data_remover.h b/chrome/browser/plugin_data_remover.h new file mode 100644 index 0000000..cbc2556 --- /dev/null +++ b/chrome/browser/plugin_data_remover.h @@ -0,0 +1,57 @@ +// 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. + +#ifndef CHROME_BROWSER_PLUGIN_DATA_REMOVER_H_ +#define CHROME_BROWSER_PLUGIN_DATA_REMOVER_H_ +#pragma once + +#include "base/ref_counted.h" +#include "base/time.h" +#include "chrome/browser/plugin_process_host.h" +#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_message.h" + +class Task; + +namespace base { +class MessageLoopProxy; +} + +class PluginDataRemover : public PluginProcessHost::Client, + public IPC::Channel::Listener { + public: + PluginDataRemover(); + ~PluginDataRemover(); + + // Starts removing plug-in data stored since |begin_time| and calls + // |done_task| on the current thread when finished. + void StartRemoving(base::Time begin_time, Task* done_task); + + // PluginProcessHost::Client methods + virtual int ID(); + virtual bool OffTheRecord(); + virtual void SetPluginInfo(const WebPluginInfo& info); + virtual void OnChannelOpened(const IPC::ChannelHandle& handle); + virtual void OnError(); + + // IPC::ChannelProxy::MessageFilter methods + virtual void OnMessageReceived(const IPC::Message& message); + virtual void OnChannelError(); + + private: + void SignalDone(); + void SignalError(); + void OnClearSiteDataResult(bool success); + void OnTimeout(); + + scoped_refptr<base::MessageLoopProxy> message_loop_; + scoped_ptr<Task> done_task_; + base::Time begin_time_; + // We own the channel, but it's used on the IO thread, so it needs to be + // deleted there as well. + IPC::Channel* channel_; + ScopedRunnableMethodFactory<PluginDataRemover> method_factory_; +}; + +#endif // CHROME_BROWSER_PLUGIN_DATA_REMOVER_H_ diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index bd37a6f..e3e23fd 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -199,11 +199,6 @@ PluginProcessHost* PluginService::FindPluginProcess( const FilePath& plugin_path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (plugin_path.value().empty()) { - NOTREACHED() << "should only be called if we have a plugin to load"; - return NULL; - } - for (BrowserChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS); !iter.Done(); ++iter) { PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); @@ -218,26 +213,25 @@ PluginProcessHost* PluginService::FindOrStartPluginProcess( const FilePath& plugin_path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - PluginProcessHost *plugin_host = FindPluginProcess(plugin_path); + PluginProcessHost* plugin_host = FindPluginProcess(plugin_path); if (plugin_host) return plugin_host; WebPluginInfo info; if (!NPAPI::PluginList::Singleton()->GetPluginInfoByPath( - plugin_path, &info)) { - DCHECK(false); + plugin_path, &info)) { + NOTREACHED(); return NULL; } // This plugin isn't loaded by any plugin process, so create a new process. - plugin_host = new PluginProcessHost(); - if (!plugin_host->Init(info, ui_locale_)) { - DCHECK(false); // Init is not expected to fail - delete plugin_host; + scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); + if (!new_host->Init(info, ui_locale_)) { + NOTREACHED(); // Init is not expected to fail return NULL; } - return plugin_host; + return new_host.release(); } void PluginService::OpenChannelToPlugin( diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 7f1fc4b..675fa77 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2380,6 +2380,8 @@ 'browser/platform_util_common_linux.cc', 'browser/platform_util_mac.mm', 'browser/platform_util_win.cc', + 'browser/plugin_data_remover.cc', + 'browser/plugin_data_remover.h', 'browser/plugin_download_helper.cc', 'browser/plugin_download_helper.h', 'browser/plugin_exceptions_table_model.cc', diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h index 6cee704..791f05a 100644 --- a/chrome/common/plugin_messages_internal.h +++ b/chrome/common/plugin_messages_internal.h @@ -308,6 +308,11 @@ IPC_BEGIN_MESSAGES(Plugin) gfx::PluginWindowHandle /* window */) #endif + IPC_MESSAGE_CONTROL3(PluginMsg_ClearSiteData, + uint64, /* flags */ + std::string, /* domain */ + base::Time /* begin_time */) + IPC_END_MESSAGES(Plugin) @@ -463,6 +468,9 @@ IPC_BEGIN_MESSAGES(PluginHost) uint64 /* surface_id */) #endif + IPC_MESSAGE_CONTROL1(PluginHostMsg_ClearSiteDataResult, + bool /* success */) + IPC_END_MESSAGES(PluginHost) //----------------------------------------------------------------------------- diff --git a/chrome/plugin/plugin_channel.cc b/chrome/plugin/plugin_channel.cc index aa3b713..0b6d5da 100644 --- a/chrome/plugin/plugin_channel.cc +++ b/chrome/plugin/plugin_channel.cc @@ -16,6 +16,7 @@ #include "chrome/plugin/plugin_thread.h" #include "chrome/plugin/webplugin_delegate_stub.h" #include "chrome/plugin/webplugin_proxy.h" +#include "webkit/glue/plugins/plugin_instance.h" #if defined(OS_POSIX) #include "base/eintr_wrapper.h" @@ -211,6 +212,7 @@ void PluginChannel::OnControlMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_DestroyInstance, OnDestroyInstance) IPC_MESSAGE_HANDLER(PluginMsg_GenerateRouteID, OnGenerateRouteID) + IPC_MESSAGE_HANDLER(PluginMsg_ClearSiteData, OnClearSiteData) IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() } @@ -256,6 +258,35 @@ int PluginChannel::GenerateRouteID() { return ++last_id; } +void PluginChannel::OnClearSiteData(uint64 flags, + const std::string& domain, + base::Time begin_time) { + bool success = false; + CommandLine* command_line = CommandLine::ForCurrentProcess(); + FilePath path = command_line->GetSwitchValuePath(switches::kPluginPath); + scoped_refptr<NPAPI::PluginLib> plugin_lib( + NPAPI::PluginLib::CreatePluginLib(path)); + if (plugin_lib.get()) { + NPError err = plugin_lib->NP_Initialize(); + if (err == NPERR_NO_ERROR) { + scoped_refptr<NPAPI::PluginInstance> instance( + plugin_lib->CreateInstance(std::string())); + + const char* domain_str = domain.empty() ? NULL : domain.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 = instance->NPP_ClearSiteData(flags, domain_str, 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); diff --git a/chrome/plugin/plugin_channel.h b/chrome/plugin/plugin_channel.h index 3fb940e..cc444c0 100644 --- a/chrome/plugin/plugin_channel.h +++ b/chrome/plugin/plugin_channel.h @@ -76,6 +76,9 @@ class PluginChannel : public PluginChannelBase { void OnCreateInstance(const std::string& mime_type, int* instance_id); void OnDestroyInstance(int instance_id, IPC::Message* reply_msg); void OnGenerateRouteID(int* route_id); + void OnClearSiteData(uint64 flags, + const std::string& domain, + base::Time begin_time); #if defined(OS_POSIX) // Close the plugin process' copy of the renderer's side of the plugin |