| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/plugin_data_remover_impl.h" | 5 #include "content/browser/plugin_data_remover_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/sequenced_task_runner_helpers.h" | 13 #include "base/sequenced_task_runner_helpers.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
| 16 #include "base/version.h" | 16 #include "base/version.h" |
| 17 #include "build/build_config.h" | 17 #include "build/build_config.h" |
| 18 #include "content/browser/plugin_process_host.h" | |
| 19 #include "content/browser/plugin_service_impl.h" | 18 #include "content/browser/plugin_service_impl.h" |
| 20 #include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.
h" | 19 #include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.
h" |
| 21 #include "content/common/child_process_host_impl.h" | 20 #include "content/common/child_process_host_impl.h" |
| 22 #include "content/common/plugin_process_messages.h" | |
| 23 #include "content/public/browser/browser_context.h" | 21 #include "content/public/browser/browser_context.h" |
| 24 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
| 25 #include "content/public/common/child_process_host.h" | 23 #include "content/public/common/child_process_host.h" |
| 26 #include "content/public/common/content_constants.h" | 24 #include "content/public/common/content_constants.h" |
| 27 #include "content/public/common/pepper_plugin_info.h" | 25 #include "content/public/common/pepper_plugin_info.h" |
| 28 #include "ppapi/proxy/ppapi_messages.h" | 26 #include "ppapi/proxy/ppapi_messages.h" |
| 29 | 27 |
| 30 namespace content { | 28 namespace content { |
| 31 | 29 |
| 32 namespace { | 30 namespace { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 54 for (std::vector<WebPluginInfo>::iterator it = plugins.begin(); | 52 for (std::vector<WebPluginInfo>::iterator it = plugins.begin(); |
| 55 it != plugins.end(); ++it) { | 53 it != plugins.end(); ++it) { |
| 56 Version version; | 54 Version version; |
| 57 WebPluginInfo::CreateVersionFromString(it->version, &version); | 55 WebPluginInfo::CreateVersionFromString(it->version, &version); |
| 58 if (version.IsValid() && min_version.CompareTo(version) == -1) | 56 if (version.IsValid() && min_version.CompareTo(version) == -1) |
| 59 supported_plugins->push_back(*it); | 57 supported_plugins->push_back(*it); |
| 60 } | 58 } |
| 61 } | 59 } |
| 62 | 60 |
| 63 class PluginDataRemoverImpl::Context | 61 class PluginDataRemoverImpl::Context |
| 64 : public PluginProcessHost::Client, | 62 : public PpapiPluginProcessHost::BrokerClient, |
| 65 public PpapiPluginProcessHost::BrokerClient, | |
| 66 public IPC::Listener, | 63 public IPC::Listener, |
| 67 public base::RefCountedThreadSafe<Context, | 64 public base::RefCountedThreadSafe<Context, |
| 68 BrowserThread::DeleteOnIOThread> { | 65 BrowserThread::DeleteOnIOThread> { |
| 69 public: | 66 public: |
| 70 Context(base::Time begin_time, BrowserContext* browser_context) | 67 Context(base::Time begin_time, BrowserContext* browser_context) |
| 71 : event_(new base::WaitableEvent(true, false)), | 68 : event_(new base::WaitableEvent(true, false)), |
| 72 begin_time_(begin_time), | 69 begin_time_(begin_time), |
| 73 is_removing_(false), | 70 is_removing_(false), |
| 74 browser_context_path_(browser_context->GetPath()), | 71 browser_context_path_(browser_context->GetPath()) { |
| 75 resource_context_(browser_context->GetResourceContext()) { | |
| 76 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 72 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 77 } | 73 } |
| 78 | 74 |
| 79 void Init(const std::string& mime_type) { | 75 void Init(const std::string& mime_type) { |
| 80 BrowserThread::PostTask( | 76 BrowserThread::PostTask( |
| 81 BrowserThread::IO, | 77 BrowserThread::IO, |
| 82 FROM_HERE, | 78 FROM_HERE, |
| 83 base::Bind(&Context::InitOnIOThread, this, mime_type)); | 79 base::Bind(&Context::InitOnIOThread, this, mime_type)); |
| 84 BrowserThread::PostDelayedTask( | 80 BrowserThread::PostDelayedTask( |
| 85 BrowserThread::IO, | 81 BrowserThread::IO, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 97 GURL(), mime_type, false, &plugins, NULL); | 93 GURL(), mime_type, false, &plugins, NULL); |
| 98 | 94 |
| 99 if (plugins.empty()) { | 95 if (plugins.empty()) { |
| 100 // May be empty for some tests and on the CrOS login OOBE screen. | 96 // May be empty for some tests and on the CrOS login OOBE screen. |
| 101 event_->Signal(); | 97 event_->Signal(); |
| 102 return; | 98 return; |
| 103 } | 99 } |
| 104 | 100 |
| 105 base::FilePath plugin_path = plugins[0].path; | 101 base::FilePath plugin_path = plugins[0].path; |
| 106 | 102 |
| 103 PepperPluginInfo* pepper_info = |
| 104 plugin_service->GetRegisteredPpapiPluginInfo(plugin_path); |
| 105 if (!pepper_info) { |
| 106 event_->Signal(); |
| 107 return; |
| 108 } |
| 109 |
| 107 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 110 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 108 remove_start_time_ = base::Time::Now(); | 111 remove_start_time_ = base::Time::Now(); |
| 109 is_removing_ = true; | 112 is_removing_ = true; |
| 110 // Balanced in On[Ppapi]ChannelOpened or OnError. Exactly one them will | 113 |
| 111 // eventually be called, so we need to keep this object around until then. | 114 // Balanced in OnPpapiChannelOpened. |
| 112 AddRef(); | 115 AddRef(); |
| 113 | 116 plugin_name_ = pepper_info->name; |
| 114 PepperPluginInfo* pepper_info = | 117 // Use the broker since we run this function outside the sandbox. |
| 115 plugin_service->GetRegisteredPpapiPluginInfo(plugin_path); | 118 plugin_service->OpenChannelToPpapiBroker(0, plugin_path, this); |
| 116 if (pepper_info) { | |
| 117 plugin_name_ = pepper_info->name; | |
| 118 // Use the broker since we run this function outside the sandbox. | |
| 119 plugin_service->OpenChannelToPpapiBroker(0, plugin_path, this); | |
| 120 } else { | |
| 121 plugin_service->OpenChannelToNpapiPlugin( | |
| 122 0, 0, GURL(), GURL(), mime_type, this); | |
| 123 } | |
| 124 } | 119 } |
| 125 | 120 |
| 126 // Called when a timeout happens in order not to block the client | 121 // Called when a timeout happens in order not to block the client |
| 127 // indefinitely. | 122 // indefinitely. |
| 128 void OnTimeout() { | 123 void OnTimeout() { |
| 129 LOG_IF(ERROR, is_removing_) << "Timed out"; | 124 LOG_IF(ERROR, is_removing_) << "Timed out"; |
| 130 SignalDone(); | 125 SignalDone(); |
| 131 } | 126 } |
| 132 | 127 |
| 133 // PluginProcessHost::Client methods. | |
| 134 int ID() override { | |
| 135 // Generate a unique identifier for this PluginProcessHostClient. | |
| 136 return ChildProcessHostImpl::GenerateChildProcessUniqueId(); | |
| 137 } | |
| 138 | |
| 139 bool OffTheRecord() override { return false; } | 128 bool OffTheRecord() override { return false; } |
| 140 | 129 |
| 141 ResourceContext* GetResourceContext() override { return resource_context_; } | |
| 142 | |
| 143 void SetPluginInfo(const WebPluginInfo& info) override {} | |
| 144 | |
| 145 void OnFoundPluginProcessHost(PluginProcessHost* host) override {} | |
| 146 | |
| 147 void OnSentPluginChannelRequest() override {} | |
| 148 | |
| 149 void OnChannelOpened(const IPC::ChannelHandle& handle) override { | |
| 150 ConnectToChannel(handle, false); | |
| 151 // Balancing the AddRef call. | |
| 152 Release(); | |
| 153 } | |
| 154 | |
| 155 void OnError() override { | |
| 156 LOG(ERROR) << "Couldn't open plugin channel"; | |
| 157 SignalDone(); | |
| 158 // Balancing the AddRef call. | |
| 159 Release(); | |
| 160 } | |
| 161 | |
| 162 // PpapiPluginProcessHost::BrokerClient implementation. | 130 // PpapiPluginProcessHost::BrokerClient implementation. |
| 163 void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle, | 131 void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle, |
| 164 int* renderer_id) override { | 132 int* renderer_id) override { |
| 165 *renderer_handle = base::kNullProcessHandle; | 133 *renderer_handle = base::kNullProcessHandle; |
| 166 *renderer_id = 0; | 134 *renderer_id = 0; |
| 167 } | 135 } |
| 168 | 136 |
| 169 void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle, | 137 void OnPpapiChannelOpened(const IPC::ChannelHandle& channel_handle, |
| 170 base::ProcessId /* peer_pid */, | 138 base::ProcessId /* peer_pid */, |
| 171 int /* child_id */) override { | 139 int /* child_id */) override { |
| 172 if (!channel_handle.name.empty()) | 140 if (!channel_handle.name.empty()) |
| 173 ConnectToChannel(channel_handle, true); | 141 ConnectToChannel(channel_handle); |
| 174 | 142 |
| 175 // Balancing the AddRef call. | 143 // Balancing the AddRef call. |
| 176 Release(); | 144 Release(); |
| 177 } | 145 } |
| 178 | 146 |
| 179 // IPC::Listener methods. | 147 // IPC::Listener methods. |
| 180 bool OnMessageReceived(const IPC::Message& message) override { | 148 bool OnMessageReceived(const IPC::Message& message) override { |
| 181 IPC_BEGIN_MESSAGE_MAP(Context, message) | 149 IPC_BEGIN_MESSAGE_MAP(Context, message) |
| 182 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ClearSiteDataResult, | |
| 183 OnClearSiteDataResult) | |
| 184 IPC_MESSAGE_HANDLER(PpapiHostMsg_ClearSiteDataResult, | 150 IPC_MESSAGE_HANDLER(PpapiHostMsg_ClearSiteDataResult, |
| 185 OnPpapiClearSiteDataResult) | 151 OnPpapiClearSiteDataResult) |
| 186 IPC_MESSAGE_UNHANDLED_ERROR() | 152 IPC_MESSAGE_UNHANDLED_ERROR() |
| 187 IPC_END_MESSAGE_MAP() | 153 IPC_END_MESSAGE_MAP() |
| 188 | 154 |
| 189 return true; | 155 return true; |
| 190 } | 156 } |
| 191 | 157 |
| 192 void OnChannelError() override { | 158 void OnChannelError() override { |
| 193 if (is_removing_) { | 159 if (is_removing_) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 215 profile_path.Append(base::FilePath(base::UTF8ToUTF16(plugin_name_))); | 181 profile_path.Append(base::FilePath(base::UTF8ToUTF16(plugin_name_))); |
| 216 #else | 182 #else |
| 217 base::FilePath plugin_data_path = | 183 base::FilePath plugin_data_path = |
| 218 profile_path.Append(base::FilePath(plugin_name_)); | 184 profile_path.Append(base::FilePath(plugin_name_)); |
| 219 #endif // defined(OS_WIN) | 185 #endif // defined(OS_WIN) |
| 220 return new PpapiMsg_ClearSiteData(0u, plugin_data_path, std::string(), | 186 return new PpapiMsg_ClearSiteData(0u, plugin_data_path, std::string(), |
| 221 kClearAllData, max_age); | 187 kClearAllData, max_age); |
| 222 } | 188 } |
| 223 | 189 |
| 224 // Connects the client side of a newly opened plugin channel. | 190 // Connects the client side of a newly opened plugin channel. |
| 225 void ConnectToChannel(const IPC::ChannelHandle& handle, bool is_ppapi) { | 191 void ConnectToChannel(const IPC::ChannelHandle& handle) { |
| 226 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 192 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 227 | 193 |
| 228 // If we timed out, don't bother connecting. | 194 // If we timed out, don't bother connecting. |
| 229 if (!is_removing_) | 195 if (!is_removing_) |
| 230 return; | 196 return; |
| 231 | 197 |
| 232 DCHECK(!channel_.get()); | 198 DCHECK(!channel_.get()); |
| 233 channel_ = IPC::Channel::CreateClient(handle, this); | 199 channel_ = IPC::Channel::CreateClient(handle, this); |
| 234 if (!channel_->Connect()) { | 200 if (!channel_->Connect()) { |
| 235 NOTREACHED() << "Couldn't connect to plugin"; | 201 NOTREACHED() << "Couldn't connect to plugin"; |
| 236 SignalDone(); | 202 SignalDone(); |
| 237 return; | 203 return; |
| 238 } | 204 } |
| 239 | 205 |
| 240 uint64_t max_age = begin_time_.is_null() | 206 uint64_t max_age = begin_time_.is_null() |
| 241 ? std::numeric_limits<uint64_t>::max() | 207 ? std::numeric_limits<uint64_t>::max() |
| 242 : (base::Time::Now() - begin_time_).InSeconds(); | 208 : (base::Time::Now() - begin_time_).InSeconds(); |
| 243 | 209 |
| 244 IPC::Message* msg; | 210 IPC::Message* msg = CreatePpapiClearSiteDataMsg(max_age); |
| 245 if (is_ppapi) { | |
| 246 msg = CreatePpapiClearSiteDataMsg(max_age); | |
| 247 } else { | |
| 248 msg = new PluginProcessMsg_ClearSiteData( | |
| 249 std::string(), kClearAllData, max_age); | |
| 250 } | |
| 251 if (!channel_->Send(msg)) { | 211 if (!channel_->Send(msg)) { |
| 252 NOTREACHED() << "Couldn't send ClearSiteData message"; | 212 NOTREACHED() << "Couldn't send ClearSiteData message"; |
| 253 SignalDone(); | 213 SignalDone(); |
| 254 return; | 214 return; |
| 255 } | 215 } |
| 256 } | 216 } |
| 257 | 217 |
| 258 // Handles the PpapiHostMsg_ClearSiteDataResult message by delegating to the | 218 // Handles the PpapiHostMsg_ClearSiteDataResult message. |
| 259 // PluginProcessHostMsg_ClearSiteDataResult handler. | |
| 260 void OnPpapiClearSiteDataResult(uint32_t request_id, bool success) { | 219 void OnPpapiClearSiteDataResult(uint32_t request_id, bool success) { |
| 261 DCHECK_EQ(0u, request_id); | 220 DCHECK_EQ(0u, request_id); |
| 262 OnClearSiteDataResult(success); | |
| 263 } | |
| 264 | |
| 265 // Handles the PluginProcessHostMsg_ClearSiteDataResult message. | |
| 266 void OnClearSiteDataResult(bool success) { | |
| 267 LOG_IF(ERROR, !success) << "ClearSiteData returned error"; | 221 LOG_IF(ERROR, !success) << "ClearSiteData returned error"; |
| 268 UMA_HISTOGRAM_TIMES("ClearPluginData.time", | 222 UMA_HISTOGRAM_TIMES("ClearPluginData.time", |
| 269 base::Time::Now() - remove_start_time_); | 223 base::Time::Now() - remove_start_time_); |
| 270 SignalDone(); | 224 SignalDone(); |
| 271 } | 225 } |
| 272 | 226 |
| 273 // Signals that we are finished with removing data (successful or not). This | 227 // Signals that we are finished with removing data (successful or not). This |
| 274 // method is safe to call multiple times. | 228 // method is safe to call multiple times. |
| 275 void SignalDone() { | 229 void SignalDone() { |
| 276 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 230 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 277 if (!is_removing_) | 231 if (!is_removing_) |
| 278 return; | 232 return; |
| 279 is_removing_ = false; | 233 is_removing_ = false; |
| 280 event_->Signal(); | 234 event_->Signal(); |
| 281 } | 235 } |
| 282 | 236 |
| 283 scoped_ptr<base::WaitableEvent> event_; | 237 scoped_ptr<base::WaitableEvent> event_; |
| 284 // The point in time when we start removing data. | 238 // The point in time when we start removing data. |
| 285 base::Time remove_start_time_; | 239 base::Time remove_start_time_; |
| 286 // The point in time from which on we remove data. | 240 // The point in time from which on we remove data. |
| 287 base::Time begin_time_; | 241 base::Time begin_time_; |
| 288 bool is_removing_; | 242 bool is_removing_; |
| 289 | 243 |
| 290 // Path for the current profile. Must be retrieved on the UI thread from the | 244 // Path for the current profile. Must be retrieved on the UI thread from the |
| 291 // browser context when we start so we can use it later on the I/O thread. | 245 // browser context when we start so we can use it later on the I/O thread. |
| 292 base::FilePath browser_context_path_; | 246 base::FilePath browser_context_path_; |
| 293 | 247 |
| 294 // The resource context for the profile. Use only on the I/O thread. | |
| 295 ResourceContext* resource_context_; | |
| 296 | |
| 297 // The name of the plugin. Use only on the I/O thread. | 248 // The name of the plugin. Use only on the I/O thread. |
| 298 std::string plugin_name_; | 249 std::string plugin_name_; |
| 299 | 250 |
| 300 // The channel is NULL until we have opened a connection to the plugin | 251 // The channel is NULL until we have opened a connection to the plugin |
| 301 // process. | 252 // process. |
| 302 scoped_ptr<IPC::Channel> channel_; | 253 scoped_ptr<IPC::Channel> channel_; |
| 303 }; | 254 }; |
| 304 | 255 |
| 305 | 256 |
| 306 PluginDataRemoverImpl::PluginDataRemoverImpl(BrowserContext* browser_context) | 257 PluginDataRemoverImpl::PluginDataRemoverImpl(BrowserContext* browser_context) |
| 307 : mime_type_(kFlashPluginSwfMimeType), | 258 : mime_type_(kFlashPluginSwfMimeType), |
| 308 browser_context_(browser_context) { | 259 browser_context_(browser_context) { |
| 309 } | 260 } |
| 310 | 261 |
| 311 PluginDataRemoverImpl::~PluginDataRemoverImpl() { | 262 PluginDataRemoverImpl::~PluginDataRemoverImpl() { |
| 312 } | 263 } |
| 313 | 264 |
| 314 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( | 265 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( |
| 315 base::Time begin_time) { | 266 base::Time begin_time) { |
| 316 DCHECK(!context_.get()); | 267 DCHECK(!context_.get()); |
| 317 context_ = new Context(begin_time, browser_context_); | 268 context_ = new Context(begin_time, browser_context_); |
| 318 context_->Init(mime_type_); | 269 context_->Init(mime_type_); |
| 319 return context_->event(); | 270 return context_->event(); |
| 320 } | 271 } |
| 321 | 272 |
| 322 } // namespace content | 273 } // namespace content |
| OLD | NEW |