| Index: chrome/browser/plugin_data_remover.cc
|
| diff --git a/chrome/browser/plugin_data_remover.cc b/chrome/browser/plugin_data_remover.cc
|
| index 4e6ac7f3c71bf5ca4a9ba8d6be6bad0c2e75bd59..1b2c6c31744bc41717c510b8e0956ecf92d27de7 100644
|
| --- a/chrome/browser/plugin_data_remover.cc
|
| +++ b/chrome/browser/plugin_data_remover.cc
|
| @@ -7,6 +7,7 @@
|
| #include "base/message_loop_proxy.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/version.h"
|
| +#include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/browser_thread.h"
|
| #include "chrome/browser/plugin_service.h"
|
| #include "chrome/common/plugin_messages.h"
|
| @@ -28,6 +29,9 @@ const uint64 kClearAllData = 0;
|
|
|
| PluginDataRemover::PluginDataRemover()
|
| : is_removing_(false),
|
| + has_browser_ref_(false),
|
| + plugin_process_(NULL),
|
| + handle_(base::kNullProcessHandle),
|
| channel_(NULL) { }
|
|
|
| PluginDataRemover::~PluginDataRemover() {
|
| @@ -36,16 +40,22 @@ PluginDataRemover::~PluginDataRemover() {
|
| BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_);
|
| }
|
|
|
| -void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) {
|
| +void PluginDataRemover::StartRemoving(const base::Time& begin_time,
|
| + bool terminate,
|
| + Task* done_task) {
|
| DCHECK(!done_task_.get());
|
| DCHECK(!is_removing_);
|
| remove_start_time_ = base::Time::Now();
|
| begin_time_ = begin_time;
|
| + terminate_process_ = terminate;
|
|
|
| message_loop_ = base::MessageLoopProxy::CreateForCurrentThread();
|
| done_task_.reset(done_task);
|
| is_removing_ = true;
|
|
|
| + // Don't quit the main message loop until the process has started.
|
| + g_browser_process->AddRefModule();
|
| + has_browser_ref_ = true;
|
| AddRef();
|
| PluginService::GetInstance()->OpenChannelToPlugin(
|
| GURL(), kFlashMimeType, this);
|
| @@ -57,6 +67,20 @@ void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) {
|
| kRemovalTimeoutMs);
|
| }
|
|
|
| +void PluginDataRemover::WaitForPluginToExit() {
|
| + DCHECK(terminate_process_);
|
| + if (!is_removing_)
|
| + return;
|
| + DCHECK_NE(base::kNullProcessHandle, handle_);
|
| + base::Time start_time(base::Time::Now());
|
| + bool result = base::WaitForSingleProcess(handle_, kRemovalTimeoutMs);
|
| + UMA_HISTOGRAM_TIMES("ClearPluginData.wait_at_shutdown",
|
| + base::Time::Now() - start_time);
|
| + UMA_HISTOGRAM_TIMES("ClearPluginData.time_at_shutdown",
|
| + base::Time::Now() - remove_start_time_);
|
| + DCHECK(result) << "Error waiting for plugin process";
|
| +}
|
| +
|
| int PluginDataRemover::ID() {
|
| // Generate an ID for the browser process.
|
| return ChildProcessInfo::GenerateChildProcessUniqueId();
|
| @@ -70,11 +94,24 @@ void PluginDataRemover::SetPluginInfo(
|
| const webkit::npapi::WebPluginInfo& info) {
|
| }
|
|
|
| +void PluginDataRemover::OnPluginProcessFound(PluginProcessHost* process) {
|
| + plugin_process_ = process;
|
| +}
|
| +
|
| void PluginDataRemover::OnChannelOpened(const IPC::ChannelHandle& handle) {
|
| ConnectToChannel(handle);
|
| + DCHECK(has_browser_ref_);
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + NewRunnableMethod(this, &PluginDataRemover::ReleaseBrowserProcess));
|
| + has_browser_ref_ = false;
|
| Release();
|
| }
|
|
|
| +void PluginDataRemover::ReleaseBrowserProcess() {
|
| + g_browser_process->ReleaseModule();
|
| +}
|
| +
|
| void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
|
|
| @@ -85,7 +122,7 @@ void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) {
|
| DCHECK(!channel_);
|
| channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this);
|
| if (!channel_->Connect()) {
|
| - LOG(DFATAL) << "Couldn't connect to plugin";
|
| + NOTREACHED() << "Couldn't connect to plugin";
|
| SignalDone();
|
| return;
|
| }
|
| @@ -94,27 +131,51 @@ void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) {
|
| new PluginMsg_ClearSiteData(std::string(),
|
| kClearAllData,
|
| begin_time_))) {
|
| - LOG(DFATAL) << "Couldn't send ClearSiteData message";
|
| + NOTREACHED() << "Couldn't send ClearSiteData message";
|
| SignalDone();
|
| + return;
|
| + }
|
| +
|
| + // Save the process handle so we can wait for the process to exit.
|
| + handle_ = plugin_process_->handle();
|
| + if (terminate_process_) {
|
| + plugin_process_->ForceShutdown();
|
| }
|
| }
|
|
|
| void PluginDataRemover::OnError() {
|
| - NOTREACHED() << "Couldn't open plugin channel";
|
| + LOG(DFATAL) << "Couldn't open plugin channel";
|
| SignalDone();
|
| + if (has_browser_ref_) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + NewRunnableMethod(this, &PluginDataRemover::ReleaseBrowserProcess));
|
| + has_browser_ref_ = false;
|
| + }
|
| Release();
|
| }
|
|
|
| void PluginDataRemover::OnClearSiteDataResult(bool success) {
|
| - if (!success)
|
| - LOG(DFATAL) << "ClearSiteData returned error";
|
| + LOG_IF(DFATAL, !success) << "ClearSiteData returned error";
|
| UMA_HISTOGRAM_TIMES("ClearPluginData.time",
|
| base::Time::Now() - remove_start_time_);
|
| SignalDone();
|
| }
|
|
|
| +void PluginDataRemover::OnPluginShuttingDown() {
|
| + VLOG(1) << "Plugin shutting down";
|
| +}
|
| +
|
| void PluginDataRemover::OnTimeout() {
|
| - NOTREACHED() << "Timed out";
|
| + if (is_removing_) {
|
| + LOG(DFATAL) << "Timed out";
|
| + if (has_browser_ref_) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + NewRunnableMethod(this, &PluginDataRemover::ReleaseBrowserProcess));
|
| + has_browser_ref_ = false;
|
| + }
|
| + }
|
| SignalDone();
|
| }
|
|
|
| @@ -122,6 +183,8 @@ bool PluginDataRemover::OnMessageReceived(const IPC::Message& msg) {
|
| IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg)
|
| IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult,
|
| OnClearSiteDataResult)
|
| + IPC_MESSAGE_HANDLER(PluginHostMsg_PluginShuttingDown,
|
| + OnPluginShuttingDown)
|
| IPC_MESSAGE_UNHANDLED_ERROR()
|
| IPC_END_MESSAGE_MAP()
|
|
|
| @@ -129,8 +192,10 @@ bool PluginDataRemover::OnMessageReceived(const IPC::Message& msg) {
|
| }
|
|
|
| void PluginDataRemover::OnChannelError() {
|
| - LOG(DFATAL) << "Channel error";
|
| - SignalDone();
|
| + if (is_removing_) {
|
| + NOTREACHED() << "Channel error";
|
| + SignalDone();
|
| + }
|
| }
|
|
|
| void PluginDataRemover::SignalDone() {
|
|
|