Index: chrome/browser/plugin_data_remover.cc |
diff --git a/chrome/browser/plugin_data_remover.cc b/chrome/browser/plugin_data_remover.cc |
index 4415c5f3d6d8755ea962180410c6f424ff245b20..5bb81960c0a993561a59b2b74870ca3e5ced26fe 100644 |
--- a/chrome/browser/plugin_data_remover.cc |
+++ b/chrome/browser/plugin_data_remover.cc |
@@ -4,63 +4,118 @@ |
#include "chrome/browser/plugin_data_remover.h" |
+#include "base/metrics/histogram.h" |
#include "base/message_loop_proxy.h" |
+#include "base/version.h" |
#include "chrome/browser/browser_thread.h" |
+#include "chrome/browser/plugin_process_host.h" |
#include "chrome/browser/plugin_service.h" |
#include "chrome/common/plugin_messages.h" |
#include "ipc/ipc_channel.h" |
+#include "webkit/glue/plugins/plugin_group.h" |
+#include "webkit/glue/plugins/plugin_list.h" |
#if defined(OS_POSIX) |
#include "ipc/ipc_channel_posix.h" |
#endif |
namespace { |
-const std::string flash_mime_type = "application/x-shockwave-flash"; |
+const char* flash_mime_type = "application/x-shockwave-flash"; |
+// TODO(bauerb): Update minimum required Flash version as soon as there is one |
+// implementing the API. |
+const char* min_flash_version = "100"; |
const int64 timeout_ms = 10000; |
jam
2010/12/13 22:41:27
can you prefix globals with "g_"
|
-} |
+} // namespace |
+ |
+class PluginDataRemover::Internal |
+ : public base::RefCountedThreadSafe<Internal>, |
+ public PluginProcessHost::Client { |
+ public: |
+ explicit Internal(PluginDataRemover* remover) : remover_(remover) { |
+ // We increase our reference count until either OnChannelOpened or OnError |
+ // is called. |
+ AddRef(); |
+ } |
+ ~Internal() { |
+ DCHECK(!remover_); |
+ } |
+ |
+ void Invalidate() { |
+ remover_ = NULL; |
+ } |
+ |
+ virtual int ID() { |
+ // Generate an ID for the browser process. |
+ return ChildProcessInfo::GenerateChildProcessUniqueId(); |
+ } |
+ |
+ virtual bool OffTheRecord() { |
+ return false; |
+ } |
+ |
+ virtual void SetPluginInfo(const WebPluginInfo& info) { } |
+ |
+ virtual void OnChannelOpened(const IPC::ChannelHandle& handle) { |
+ if (remover_) |
+ remover_->OnChannelOpened(handle); |
+ Release(); |
+ } |
+ |
+ virtual void OnError() { |
+ if (remover_) { |
+ LOG(DFATAL) << "Couldn't open plugin channel"; |
+ remover_->SignalDone(); |
+ } |
+ Release(); |
+ } |
+ |
+ void OnTimeout() { |
+ if (remover_) { |
+ LOG(DFATAL) << "Timed out"; |
+ remover_->SignalDone(); |
+ } |
+ } |
+ |
+ private: |
+ PluginDataRemover* remover_; |
+}; |
PluginDataRemover::PluginDataRemover() |
- : channel_(NULL), |
- method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
-} |
+ : is_removing_(false), |
+ channel_(NULL) { } |
PluginDataRemover::~PluginDataRemover() { |
- DCHECK(!done_task_.get()); |
- if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_)) |
- delete channel_; |
+ DCHECK(!is_removing_); |
+ if (channel_) |
+ BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); |
} |
void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) { |
DCHECK(!done_task_.get()); |
+ DCHECK(!is_removing_); |
+ remove_start_time_ = base::Time::Now(); |
begin_time_ = begin_time; |
message_loop_ = base::MessageLoopProxy::CreateForCurrentThread(); |
done_task_.reset(done_task); |
+ is_removing_ = true; |
+ internal_ = make_scoped_refptr(new Internal(this)); |
PluginService::GetInstance()->OpenChannelToPlugin( |
- GURL(), flash_mime_type, this); |
+ GURL(), |
+ flash_mime_type, |
+ internal_); |
BrowserThread::PostDelayedTask( |
BrowserThread::IO, |
FROM_HERE, |
- method_factory_.NewRunnableMethod(&PluginDataRemover::OnTimeout), |
+ NewRunnableMethod(internal_.get(), &Internal::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. |
@@ -69,30 +124,23 @@ void PluginDataRemover::OnChannelOpened(const IPC::ChannelHandle& handle) { |
#endif |
channel_ = new IPC::Channel(handle.name, IPC::Channel::MODE_CLIENT, this); |
if (!channel_->Connect()) { |
- NOTREACHED() << "Couldn't connect to plugin"; |
+ LOG(DFATAL) << "Couldn't connect to plugin"; |
SignalDone(); |
return; |
} |
if (!channel_->Send( |
new PluginMsg_ClearSiteData(0, std::string(), begin_time_))) { |
- NOTREACHED() << "Couldn't send ClearSiteData message"; |
+ LOG(DFATAL) << "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"; |
+ if (!success) |
+ LOG(DFATAL) << "ClearSiteData returned error"; |
+ UMA_HISTOGRAM_TIMES("ClearPluginData.time", |
+ base::Time::Now() - remove_start_time_); |
SignalDone(); |
} |
@@ -105,14 +153,39 @@ void PluginDataRemover::OnMessageReceived(const IPC::Message& msg) { |
} |
void PluginDataRemover::OnChannelError() { |
- NOTREACHED() << "Channel error"; |
+ LOG(DFATAL) << "Channel error"; |
SignalDone(); |
} |
void PluginDataRemover::SignalDone() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (!done_task_.get()) |
+ if (!is_removing_) |
return; |
- message_loop_->PostTask(FROM_HERE, done_task_.release()); |
- message_loop_ = NULL; |
+ is_removing_ = false; |
+ if (done_task_.get()) { |
+ message_loop_->PostTask(FROM_HERE, done_task_.release()); |
+ message_loop_ = NULL; |
+ } |
+ internal_->Invalidate(); |
+} |
+ |
+// static |
+bool PluginDataRemover::IsSupported() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ bool allow_wildcard = false; |
+ WebPluginInfo plugin; |
+ std::string mime_type; |
+ if (!NPAPI::PluginList::Singleton()->GetPluginInfo(GURL(), |
+ flash_mime_type, |
+ allow_wildcard, |
+ &plugin, |
+ &mime_type)) |
+ return false; |
+ scoped_ptr<Version> version( |
+ PluginGroup::CreateVersionFromString(plugin.version)); |
+ scoped_ptr<Version> min_version( |
+ Version::GetVersionFromString(min_flash_version)); |
+ return plugin.enabled && |
+ version.get() |
+ && min_version->CompareTo(*version) == -1; |
} |