Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
| 10 #include "base/version.h" | 10 #include "base/version.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 if (rv) | 53 if (rv) |
| 54 *plugin = *plugin_it; | 54 *plugin = *plugin_it; |
| 55 return rv; | 55 return rv; |
| 56 } | 56 } |
| 57 | 57 |
| 58 } | 58 } |
| 59 | 59 |
| 60 class PluginDataRemoverImpl::Context | 60 class PluginDataRemoverImpl::Context |
| 61 : public PluginProcessHost::Client, | 61 : public PluginProcessHost::Client, |
| 62 public IPC::Channel::Listener, | 62 public IPC::Channel::Listener, |
| 63 public base::RefCountedThreadSafe<Context> { | 63 public base::RefCountedThreadSafe<Context, |
| 64 BrowserThread::DeleteOnIOThread> { | |
| 64 public: | 65 public: |
| 65 Context(const std::string& mime_type, | 66 Context(base::Time begin_time, |
| 66 base::Time begin_time, | |
| 67 const content::ResourceContext& resource_context) | 67 const content::ResourceContext& resource_context) |
| 68 : event_(new base::WaitableEvent(true, false)), | 68 : event_(new base::WaitableEvent(true, false)), |
| 69 begin_time_(begin_time), | 69 begin_time_(begin_time), |
| 70 is_removing_(false), | 70 is_removing_(false), |
| 71 resource_context_(resource_context), | 71 resource_context_(resource_context), |
| 72 channel_(NULL) { | 72 channel_(NULL) { |
| 73 } | |
| 74 | |
| 75 virtual ~Context() { | |
| 76 } | |
| 77 | |
| 78 // Initialize on the IO thread. | |
| 79 void Init(const std::string& mime_type) { | |
| 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 81 remove_start_time_ = base::Time::Now(); | |
| 82 is_removing_ = true; | |
| 73 // Balanced in OnChannelOpened or OnError. Exactly one them will eventually | 83 // Balanced in OnChannelOpened or OnError. Exactly one them will eventually |
| 74 // be called, so we need to keep this object around until then. | 84 // be called, so we need to keep this object around until then. |
| 75 AddRef(); | 85 AddRef(); |
| 76 remove_start_time_ = base::Time::Now(); | 86 PluginService::GetInstance()->OpenChannelToNpapiPlugin( |
| 77 BrowserThread::PostTask( | 87 0, 0, GURL(), GURL(), mime_type, this); |
| 78 BrowserThread::IO, | |
| 79 FROM_HERE, | |
| 80 base::Bind(&Context::Init, this, mime_type)); | |
| 81 | |
| 82 BrowserThread::PostDelayedTask( | |
| 83 BrowserThread::IO, | |
| 84 FROM_HERE, | |
| 85 base::Bind(&Context::OnTimeout, this), | |
| 86 kRemovalTimeoutMs); | |
| 87 } | 88 } |
| 88 | 89 |
| 89 virtual ~Context() { | 90 // Called when a timeout happens in order not to block the client |
| 90 if (channel_) | 91 // indefinitely. |
| 91 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); | 92 void OnTimeout() { |
| 93 LOG_IF(ERROR, is_removing_) << "Timed out"; | |
| 94 SignalDone(); | |
| 92 } | 95 } |
| 93 | 96 |
| 94 // PluginProcessHost::Client methods. | 97 // PluginProcessHost::Client methods. |
| 95 virtual int ID() OVERRIDE { | 98 virtual int ID() OVERRIDE { |
| 96 // Generate a unique identifier for this PluginProcessHostClient. | 99 // Generate a unique identifier for this PluginProcessHostClient. |
| 97 return ChildProcessHostImpl::GenerateChildProcessUniqueId(); | 100 return ChildProcessHostImpl::GenerateChildProcessUniqueId(); |
| 98 } | 101 } |
| 99 | 102 |
| 100 virtual bool OffTheRecord() OVERRIDE { | 103 virtual bool OffTheRecord() OVERRIDE { |
| 101 return false; | 104 return false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 return true; | 141 return true; |
| 139 } | 142 } |
| 140 | 143 |
| 141 virtual void OnChannelError() OVERRIDE { | 144 virtual void OnChannelError() OVERRIDE { |
| 142 if (is_removing_) { | 145 if (is_removing_) { |
| 143 NOTREACHED() << "Channel error"; | 146 NOTREACHED() << "Channel error"; |
| 144 SignalDone(); | 147 SignalDone(); |
| 145 } | 148 } |
| 146 } | 149 } |
| 147 | 150 |
| 148 | |
| 149 base::WaitableEvent* event() { return event_.get(); } | 151 base::WaitableEvent* event() { return event_.get(); } |
| 150 | 152 |
| 151 private: | 153 private: |
| 152 // Initialize on the IO thread. | |
| 153 void Init(const std::string& mime_type) { | |
| 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 155 is_removing_ = true; | |
| 156 PluginService::GetInstance()->OpenChannelToNpapiPlugin( | |
| 157 0, 0, GURL(), GURL(), mime_type, this); | |
| 158 } | |
| 159 | |
| 160 // Connects the client side of a newly opened plug-in channel. | 154 // Connects the client side of a newly opened plug-in channel. |
| 161 void ConnectToChannel(const IPC::ChannelHandle& handle) { | 155 void ConnectToChannel(const IPC::ChannelHandle& handle) { |
| 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 163 | 157 |
| 164 // If we timed out, don't bother connecting. | 158 // If we timed out, don't bother connecting. |
| 165 if (!is_removing_) | 159 if (!is_removing_) |
| 166 return; | 160 return; |
| 167 | 161 |
| 168 DCHECK(!channel_); | 162 DCHECK(!channel_.get()); |
| 169 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); | 163 channel_.reset(new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this)); |
| 170 if (!channel_->Connect()) { | 164 if (!channel_->Connect()) { |
| 171 NOTREACHED() << "Couldn't connect to plugin"; | 165 NOTREACHED() << "Couldn't connect to plugin"; |
| 172 SignalDone(); | 166 SignalDone(); |
| 173 return; | 167 return; |
| 174 } | 168 } |
| 175 | 169 |
| 176 if (!channel_->Send(new PluginMsg_ClearSiteData(std::string(), | 170 if (!channel_->Send(new PluginMsg_ClearSiteData(std::string(), |
| 177 kClearAllData, | 171 kClearAllData, |
| 178 begin_time_))) { | 172 begin_time_))) { |
| 179 NOTREACHED() << "Couldn't send ClearSiteData message"; | 173 NOTREACHED() << "Couldn't send ClearSiteData message"; |
| 180 SignalDone(); | 174 SignalDone(); |
| 181 return; | 175 return; |
| 182 } | 176 } |
| 183 } | 177 } |
| 184 | 178 |
| 185 // Handles the PluginHostMsg_ClearSiteDataResult message. | 179 // Handles the PluginHostMsg_ClearSiteDataResult message. |
| 186 void OnClearSiteDataResult(bool success) { | 180 void OnClearSiteDataResult(bool success) { |
| 187 LOG_IF(ERROR, !success) << "ClearSiteData returned error"; | 181 LOG_IF(ERROR, !success) << "ClearSiteData returned error"; |
| 188 UMA_HISTOGRAM_TIMES("ClearPluginData.time", | 182 UMA_HISTOGRAM_TIMES("ClearPluginData.time", |
| 189 base::Time::Now() - remove_start_time_); | 183 base::Time::Now() - remove_start_time_); |
| 190 SignalDone(); | 184 SignalDone(); |
| 191 } | 185 } |
| 192 | 186 |
| 193 // Called when a timeout happens in order not to block the client | |
| 194 // indefinitely. | |
| 195 void OnTimeout() { | |
| 196 LOG_IF(ERROR, is_removing_) << "Timed out"; | |
| 197 SignalDone(); | |
| 198 } | |
| 199 | |
| 200 // Signals that we are finished with removing data (successful or not). This | 187 // Signals that we are finished with removing data (successful or not). This |
| 201 // method is safe to call multiple times. | 188 // method is safe to call multiple times. |
| 202 void SignalDone() { | 189 void SignalDone() { |
| 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 204 if (!is_removing_) | 191 if (!is_removing_) |
| 205 return; | 192 return; |
| 206 is_removing_ = false; | 193 is_removing_ = false; |
| 207 event_->Signal(); | 194 event_->Signal(); |
| 208 } | 195 } |
| 209 | 196 |
| 210 scoped_ptr<base::WaitableEvent> event_; | 197 scoped_ptr<base::WaitableEvent> event_; |
| 211 // The point in time when we start removing data. | 198 // The point in time when we start removing data. |
| 212 base::Time remove_start_time_; | 199 base::Time remove_start_time_; |
| 213 // The point in time from which on we remove data. | 200 // The point in time from which on we remove data. |
| 214 base::Time begin_time_; | 201 base::Time begin_time_; |
| 215 bool is_removing_; | 202 bool is_removing_; |
| 216 | 203 |
| 217 // The resource context for the profile. | 204 // The resource context for the profile. |
| 218 const content::ResourceContext& resource_context_; | 205 const content::ResourceContext& resource_context_; |
| 219 | 206 |
| 220 // We own the channel, but it's used on the IO thread, so it needs to be | 207 // The channel is NULL until we have opened a connection to the plug-in |
| 221 // deleted there. It's NULL until we have opened a connection to the plug-in | |
| 222 // process. | 208 // process. |
| 223 IPC::Channel* channel_; | 209 scoped_ptr<IPC::Channel> channel_; |
| 224 }; | 210 }; |
| 225 | 211 |
| 226 | 212 |
| 227 PluginDataRemoverImpl::PluginDataRemoverImpl( | 213 PluginDataRemoverImpl::PluginDataRemoverImpl( |
| 228 const content::ResourceContext& resource_context) | 214 const content::ResourceContext& resource_context) |
| 229 : mime_type_(kFlashMimeType), | 215 : mime_type_(kFlashMimeType), |
| 230 resource_context_(resource_context) { | 216 resource_context_(resource_context) { |
| 231 } | 217 } |
| 232 | 218 |
| 233 PluginDataRemoverImpl::~PluginDataRemoverImpl() { | 219 PluginDataRemoverImpl::~PluginDataRemoverImpl() { |
| 234 } | 220 } |
| 235 | 221 |
| 236 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( | 222 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( |
| 237 base::Time begin_time) { | 223 base::Time begin_time) { |
| 238 DCHECK(!context_.get()); | 224 DCHECK(!context_.get()); |
| 239 context_ = new Context(mime_type_, begin_time, resource_context_); | 225 context_ = new Context(begin_time, resource_context_); |
| 226 BrowserThread::PostTask( | |
|
jam
2011/12/07 21:57:12
nit: usually this is solved by having an Init func
Bernhard Bauer
2011/12/08 09:43:17
Done.
| |
| 227 BrowserThread::IO, | |
| 228 FROM_HERE, | |
| 229 base::Bind(&Context::Init, context_, mime_type_)); | |
| 230 | |
| 231 BrowserThread::PostDelayedTask( | |
| 232 BrowserThread::IO, | |
| 233 FROM_HERE, | |
| 234 base::Bind(&Context::OnTimeout, context_), | |
| 235 kRemovalTimeoutMs); | |
| 236 | |
| 240 return context_->event(); | 237 return context_->event(); |
| 241 } | 238 } |
| OLD | NEW |