plugin_data_remover.cc revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/plugin_data_remover.h" 6 7#include "base/message_loop_proxy.h" 8#include "base/metrics/histogram.h" 9#include "base/version.h" 10#include "chrome/browser/browser_thread.h" 11#include "chrome/browser/plugin_service.h" 12#include "chrome/common/plugin_messages.h" 13#include "webkit/plugins/npapi/plugin_group.h" 14#include "webkit/plugins/npapi/plugin_list.h" 15 16#if defined(OS_POSIX) 17#include "ipc/ipc_channel_posix.h" 18#endif 19 20namespace { 21const char* g_flash_mime_type = "application/x-shockwave-flash"; 22// TODO(bauerb): Update minimum required Flash version as soon as there is one 23// implementing the API. 24const char* g_min_flash_version = "100"; 25const int64 g_timeout_ms = 10000; 26} // namespace 27 28PluginDataRemover::PluginDataRemover() 29 : is_removing_(false), 30 channel_(NULL) { } 31 32PluginDataRemover::~PluginDataRemover() { 33 DCHECK(!is_removing_); 34 if (channel_) 35 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); 36} 37 38void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) { 39 DCHECK(!done_task_.get()); 40 DCHECK(!is_removing_); 41 remove_start_time_ = base::Time::Now(); 42 begin_time_ = begin_time; 43 44 message_loop_ = base::MessageLoopProxy::CreateForCurrentThread(); 45 done_task_.reset(done_task); 46 is_removing_ = true; 47 48 AddRef(); 49 PluginService::GetInstance()->OpenChannelToPlugin( 50 GURL(), g_flash_mime_type, this); 51 52 BrowserThread::PostDelayedTask( 53 BrowserThread::IO, 54 FROM_HERE, 55 NewRunnableMethod(this, &PluginDataRemover::OnTimeout), 56 g_timeout_ms); 57} 58 59int PluginDataRemover::ID() { 60 // Generate an ID for the browser process. 61 return ChildProcessInfo::GenerateChildProcessUniqueId(); 62} 63 64bool PluginDataRemover::OffTheRecord() { 65 return false; 66} 67 68void PluginDataRemover::SetPluginInfo( 69 const webkit::npapi::WebPluginInfo& info) { 70} 71 72void PluginDataRemover::OnChannelOpened(const IPC::ChannelHandle& handle) { 73 ConnectToChannel(handle); 74 Release(); 75} 76 77void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) { 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 79 80 // If we timed out, don't bother connecting. 81 if (!is_removing_) 82 return; 83 84 DCHECK(!channel_); 85 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); 86 if (!channel_->Connect()) { 87 LOG(DFATAL) << "Couldn't connect to plugin"; 88 SignalDone(); 89 return; 90 } 91 92 if (!channel_->Send( 93 new PluginMsg_ClearSiteData(0, std::string(), begin_time_))) { 94 LOG(DFATAL) << "Couldn't send ClearSiteData message"; 95 SignalDone(); 96 } 97} 98 99void PluginDataRemover::OnError() { 100 NOTREACHED() << "Couldn't open plugin channel"; 101 SignalDone(); 102 Release(); 103} 104 105void PluginDataRemover::OnClearSiteDataResult(bool success) { 106 if (!success) 107 LOG(DFATAL) << "ClearSiteData returned error"; 108 UMA_HISTOGRAM_TIMES("ClearPluginData.time", 109 base::Time::Now() - remove_start_time_); 110 SignalDone(); 111} 112 113void PluginDataRemover::OnTimeout() { 114 NOTREACHED() << "Timed out"; 115 SignalDone(); 116} 117 118bool PluginDataRemover::OnMessageReceived(const IPC::Message& msg) { 119 IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg) 120 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, 121 OnClearSiteDataResult) 122 IPC_MESSAGE_UNHANDLED_ERROR() 123 IPC_END_MESSAGE_MAP() 124 125 return true; 126} 127 128void PluginDataRemover::OnChannelError() { 129 LOG(DFATAL) << "Channel error"; 130 SignalDone(); 131} 132 133void PluginDataRemover::SignalDone() { 134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 135 if (!is_removing_) 136 return; 137 is_removing_ = false; 138 if (done_task_.get()) { 139 message_loop_->PostTask(FROM_HERE, done_task_.release()); 140 message_loop_ = NULL; 141 } 142} 143 144// static 145bool PluginDataRemover::IsSupported() { 146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 147 bool allow_wildcard = false; 148 webkit::npapi::WebPluginInfo plugin; 149 std::string mime_type; 150 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfo(GURL(), 151 g_flash_mime_type, 152 allow_wildcard, 153 &plugin, 154 &mime_type)) 155 return false; 156 scoped_ptr<Version> version( 157 webkit::npapi::PluginGroup::CreateVersionFromString(plugin.version)); 158 scoped_ptr<Version> min_version( 159 Version::GetVersionFromString(g_min_flash_version)); 160 return plugin.enabled && 161 version.get() && 162 min_version->CompareTo(*version) == -1; 163} 164