Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: content/browser/plugin_data_remover_impl.cc

Issue 9981015: Add an interface for Flash to clear its data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "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/utf_string_conversions.h"
10 #include "base/version.h" 11 #include "base/version.h"
11 #include "content/browser/plugin_process_host.h" 12 #include "content/browser/plugin_process_host.h"
12 #include "content/browser/plugin_service_impl.h" 13 #include "content/browser/plugin_service_impl.h"
14 #include "content/browser/renderer_host/pepper_file_message_filter.h"
13 #include "content/common/child_process_host_impl.h" 15 #include "content/common/child_process_host_impl.h"
14 #include "content/common/plugin_messages.h" 16 #include "content/common/plugin_messages.h"
17 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/common/pepper_plugin_info.h"
20 #include "ppapi/proxy/ppapi_messages.h"
16 #include "webkit/plugins/npapi/plugin_group.h" 21 #include "webkit/plugins/npapi/plugin_group.h"
17 22
18 using content::BrowserThread; 23 namespace content {
19 using content::ChildProcessHostImpl;
20 24
21 namespace { 25 namespace {
22 26
23 const char kFlashMimeType[] = "application/x-shockwave-flash"; 27 const char kFlashMimeType[] = "application/x-shockwave-flash";
24 // The minimum Flash Player version that implements NPP_ClearSiteData. 28 // The minimum Flash Player version that implements NPP_ClearSiteData.
25 const char kMinFlashVersion[] = "10.3"; 29 const char kMinFlashVersion[] = "10.3";
26 const int64 kRemovalTimeoutMs = 10000; 30 const int64 kRemovalTimeoutMs = 10000;
27 const uint64 kClearAllData = 0; 31 const uint64 kClearAllData = 0;
28 32
29 } // namespace 33 } // namespace
30 34
31 namespace content {
32
33 // static 35 // static
34 PluginDataRemover* PluginDataRemover::Create( 36 PluginDataRemover* PluginDataRemover::Create(BrowserContext* browser_context) {
35 content::ResourceContext* resource_context) { 37 return new PluginDataRemoverImpl(browser_context);
36 return new PluginDataRemoverImpl(resource_context);
37 } 38 }
38 39
39 // static 40 // static
40 bool PluginDataRemover::IsSupported(webkit::WebPluginInfo* plugin) { 41 bool PluginDataRemover::IsSupported(webkit::WebPluginInfo* plugin) {
41 bool allow_wildcard = false; 42 bool allow_wildcard = false;
42 std::vector<webkit::WebPluginInfo> plugins; 43 std::vector<webkit::WebPluginInfo> plugins;
43 PluginService::GetInstance()->GetPluginInfoArray( 44 PluginService::GetInstance()->GetPluginInfoArray(
44 GURL(), kFlashMimeType, allow_wildcard, &plugins, NULL); 45 GURL(), kFlashMimeType, allow_wildcard, &plugins, NULL);
45 std::vector<webkit::WebPluginInfo>::iterator plugin_it = plugins.begin(); 46 std::vector<webkit::WebPluginInfo>::iterator plugin_it = plugins.begin();
46 if (plugin_it == plugins.end()) 47 if (plugin_it == plugins.end())
47 return false; 48 return false;
48 scoped_ptr<Version> version( 49 scoped_ptr<Version> version(
49 webkit::npapi::PluginGroup::CreateVersionFromString(plugin_it->version)); 50 webkit::npapi::PluginGroup::CreateVersionFromString(plugin_it->version));
50 scoped_ptr<Version> min_version( 51 scoped_ptr<Version> min_version(
51 Version::GetVersionFromString(kMinFlashVersion)); 52 Version::GetVersionFromString(kMinFlashVersion));
52 bool rv = version.get() && min_version->CompareTo(*version) == -1; 53 bool rv = version.get() && min_version->CompareTo(*version) == -1;
53 if (rv) 54 if (rv)
54 *plugin = *plugin_it; 55 *plugin = *plugin_it;
55 return rv; 56 return rv;
56 } 57 }
57 58
58 }
59
60 class PluginDataRemoverImpl::Context 59 class PluginDataRemoverImpl::Context
61 : public PluginProcessHost::Client, 60 : public PluginProcessHost::Client,
61 public PpapiPluginProcessHost::BrokerClient,
62 public IPC::Channel::Listener, 62 public IPC::Channel::Listener,
63 public base::RefCountedThreadSafe<Context, 63 public base::RefCountedThreadSafe<Context,
64 BrowserThread::DeleteOnIOThread> { 64 BrowserThread::DeleteOnIOThread> {
65 public: 65 public:
66 Context(base::Time begin_time, 66 Context(base::Time begin_time, BrowserContext* browser_context)
67 content::ResourceContext* resource_context)
68 : event_(new base::WaitableEvent(true, false)), 67 : event_(new base::WaitableEvent(true, false)),
69 begin_time_(begin_time), 68 begin_time_(begin_time),
70 is_removing_(false), 69 is_removing_(false),
71 resource_context_(resource_context), 70 browser_context_path_(browser_context->GetPath()),
71 resource_context_(browser_context->GetResourceContext()),
72 channel_(NULL) { 72 channel_(NULL) {
73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
73 } 74 }
74 75
75 virtual ~Context() { 76 virtual ~Context() {
76 } 77 }
77 78
78 void Init(const std::string& mime_type) { 79 void Init(const std::string& mime_type) {
79 BrowserThread::PostTask( 80 BrowserThread::PostTask(
80 BrowserThread::IO, 81 BrowserThread::IO,
81 FROM_HERE, 82 FROM_HERE,
82 base::Bind(&Context::InitOnIOThread, this, mime_type)); 83 base::Bind(&Context::InitOnIOThread, this, mime_type));
83 BrowserThread::PostDelayedTask( 84 BrowserThread::PostDelayedTask(
84 BrowserThread::IO, 85 BrowserThread::IO,
85 FROM_HERE, 86 FROM_HERE,
86 base::Bind(&Context::OnTimeout, this), 87 base::Bind(&Context::OnTimeout, this),
87 base::TimeDelta::FromMilliseconds(kRemovalTimeoutMs)); 88 base::TimeDelta::FromMilliseconds(kRemovalTimeoutMs));
88 } 89 }
89 90
90 // Initialize on the IO thread.
91 void InitOnIOThread(const std::string& mime_type) { 91 void InitOnIOThread(const std::string& mime_type) {
92 PluginServiceImpl* plugin_service = PluginServiceImpl::GetInstance();
93
94 // Get the plugin file path.
95 std::vector<webkit::WebPluginInfo> plugins;
96 plugin_service->GetPluginInfoArray(
97 GURL(), mime_type, false, &plugins, NULL);
98 FilePath plugin_path;
99 if (!plugins.empty()) // May be empty for some tests.
100 plugin_path = plugins[0].path;
101
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
93 remove_start_time_ = base::Time::Now(); 103 remove_start_time_ = base::Time::Now();
94 is_removing_ = true; 104 is_removing_ = true;
95 // Balanced in OnChannelOpened or OnError. Exactly one them will eventually 105 // Balanced in On[Ppapi]ChannelOpened or OnError. Exactly one them will
96 // be called, so we need to keep this object around until then. 106 // eventually be called, so we need to keep this object around until then.
97 AddRef(); 107 AddRef();
98 PluginServiceImpl::GetInstance()->OpenChannelToNpapiPlugin( 108
99 0, 0, GURL(), GURL(), mime_type, this); 109 PepperPluginInfo* pepper_info =
110 plugin_service->GetRegisteredPpapiPluginInfo(plugin_path);
111 if (pepper_info) {
112 // Use the broker since we run this function outside the sandbox.
113 plugin_service->OpenChannelToPpapiBroker(plugin_path, this);
114 } else {
115 plugin_service->OpenChannelToNpapiPlugin(
116 0, 0, GURL(), GURL(), mime_type, this);
117 }
100 } 118 }
101 119
102 // Called when a timeout happens in order not to block the client 120 // Called when a timeout happens in order not to block the client
103 // indefinitely. 121 // indefinitely.
104 void OnTimeout() { 122 void OnTimeout() {
105 LOG_IF(ERROR, is_removing_) << "Timed out"; 123 LOG_IF(ERROR, is_removing_) << "Timed out";
106 SignalDone(); 124 SignalDone();
107 } 125 }
108 126
109 // PluginProcessHost::Client methods. 127 // PluginProcessHost::Client methods.
110 virtual int ID() OVERRIDE { 128 virtual int ID() OVERRIDE {
111 // Generate a unique identifier for this PluginProcessHostClient. 129 // Generate a unique identifier for this PluginProcessHostClient.
112 return ChildProcessHostImpl::GenerateChildProcessUniqueId(); 130 return ChildProcessHostImpl::GenerateChildProcessUniqueId();
113 } 131 }
114 132
115 virtual bool OffTheRecord() OVERRIDE { 133 virtual bool OffTheRecord() OVERRIDE {
116 return false; 134 return false;
117 } 135 }
118 136
119 virtual content::ResourceContext* GetResourceContext() OVERRIDE { 137 virtual ResourceContext* GetResourceContext() OVERRIDE {
120 return resource_context_; 138 return resource_context_;
121 } 139 }
122 140
123 virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE { 141 virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE {
124 } 142 }
125 143
126 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE { 144 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
127 } 145 }
128 146
129 virtual void OnSentPluginChannelRequest() OVERRIDE { 147 virtual void OnSentPluginChannelRequest() OVERRIDE {
130 } 148 }
131 149
132 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE { 150 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE {
133 ConnectToChannel(handle); 151 ConnectToChannel(handle, false);
134 // Balancing the AddRef call. 152 // Balancing the AddRef call.
135 Release(); 153 Release();
136 } 154 }
137 155
138 virtual void OnError() OVERRIDE { 156 virtual void OnError() OVERRIDE {
139 LOG(ERROR) << "Couldn't open plugin channel"; 157 LOG(ERROR) << "Couldn't open plugin channel";
140 SignalDone(); 158 SignalDone();
141 // Balancing the AddRef call. 159 // Balancing the AddRef call.
142 Release(); 160 Release();
143 } 161 }
144 162
163 // PpapiPluginProcessHost::BrokerClient implementation.
164 virtual void GetPpapiChannelInfo(base::ProcessHandle* renderer_handle,
165 int* renderer_id) OVERRIDE {
166 *renderer_id = 0;
167 }
168
169 virtual void OnPpapiChannelOpened(
170 base::ProcessHandle plugin_process_handle,
171 const IPC::ChannelHandle& channel_handle) OVERRIDE {
172 if (plugin_process_handle != base::kNullProcessHandle)
173 ConnectToChannel(channel_handle, true);
174
175 // Balancing the AddRef call.
176 Release();
177 }
178
145 // IPC::Channel::Listener methods. 179 // IPC::Channel::Listener methods.
146 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 180 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
147 IPC_BEGIN_MESSAGE_MAP(Context, message) 181 IPC_BEGIN_MESSAGE_MAP(Context, message)
148 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, 182 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult,
149 OnClearSiteDataResult) 183 OnClearSiteDataResult)
184 IPC_MESSAGE_HANDLER(PpapiHostMsg_ClearSiteDataResult,
185 OnClearSiteDataResult)
150 IPC_MESSAGE_UNHANDLED_ERROR() 186 IPC_MESSAGE_UNHANDLED_ERROR()
151 IPC_END_MESSAGE_MAP() 187 IPC_END_MESSAGE_MAP()
152 188
153 return true; 189 return true;
154 } 190 }
155 191
156 virtual void OnChannelError() OVERRIDE { 192 virtual void OnChannelError() OVERRIDE {
157 if (is_removing_) { 193 if (is_removing_) {
158 NOTREACHED() << "Channel error"; 194 NOTREACHED() << "Channel error";
159 SignalDone(); 195 SignalDone();
160 } 196 }
161 } 197 }
162 198
163 base::WaitableEvent* event() { return event_.get(); } 199 base::WaitableEvent* event() { return event_.get(); }
164 200
165 private: 201 private:
166 // Connects the client side of a newly opened plug-in channel. 202 // Connects the client side of a newly opened plug-in channel.
167 void ConnectToChannel(const IPC::ChannelHandle& handle) { 203 void ConnectToChannel(const IPC::ChannelHandle& handle, bool is_ppapi) {
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
169 205
170 // If we timed out, don't bother connecting. 206 // If we timed out, don't bother connecting.
171 if (!is_removing_) 207 if (!is_removing_)
172 return; 208 return;
173 209
174 DCHECK(!channel_.get()); 210 DCHECK(!channel_.get());
175 channel_.reset(new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this)); 211 channel_.reset(new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this));
176 if (!channel_->Connect()) { 212 if (!channel_->Connect()) {
177 NOTREACHED() << "Couldn't connect to plugin"; 213 NOTREACHED() << "Couldn't connect to plugin";
178 SignalDone(); 214 SignalDone();
179 return; 215 return;
180 } 216 }
181 217
182 if (!channel_->Send(new PluginMsg_ClearSiteData(std::string(), 218 uint64 max_age = begin_time_.is_null() ?
183 kClearAllData, 219 std::numeric_limits<uint64>::max() :
184 begin_time_))) { 220 (base::Time::Now() - begin_time_).InSeconds();
221
222 IPC::Message* msg;
223 if (is_ppapi) {
224 // Pass the path as 8-bit on all platforms.
225 FilePath profile_path =
226 PepperFileMessageFilter::GetDataDirName(browser_context_path_);
227 #if defined(OS_WIN)
228 std::string path_utf8 = UTF16ToUTF8(profile_path.value());
229 #else
230 const std::string& path_utf8 = profile_path.value();
231 #endif
232 msg = new PpapiMsg_ClearSiteData(profile_path, path_utf8,
233 kClearAllData, max_age);
234 } else {
235 msg = new PluginMsg_ClearSiteData(std::string(), kClearAllData, max_age);
236 }
237 if (!channel_->Send(msg)) {
185 NOTREACHED() << "Couldn't send ClearSiteData message"; 238 NOTREACHED() << "Couldn't send ClearSiteData message";
186 SignalDone(); 239 SignalDone();
187 return; 240 return;
188 } 241 }
189 } 242 }
190 243
191 // Handles the PluginHostMsg_ClearSiteDataResult message. 244 // Handles the *HostMsg_ClearSiteDataResult message.
192 void OnClearSiteDataResult(bool success) { 245 void OnClearSiteDataResult(bool success) {
193 LOG_IF(ERROR, !success) << "ClearSiteData returned error"; 246 LOG_IF(ERROR, !success) << "ClearSiteData returned error";
194 UMA_HISTOGRAM_TIMES("ClearPluginData.time", 247 UMA_HISTOGRAM_TIMES("ClearPluginData.time",
195 base::Time::Now() - remove_start_time_); 248 base::Time::Now() - remove_start_time_);
196 SignalDone(); 249 SignalDone();
197 } 250 }
198 251
199 // Signals that we are finished with removing data (successful or not). This 252 // Signals that we are finished with removing data (successful or not). This
200 // method is safe to call multiple times. 253 // method is safe to call multiple times.
201 void SignalDone() { 254 void SignalDone() {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
203 if (!is_removing_) 256 if (!is_removing_)
204 return; 257 return;
205 is_removing_ = false; 258 is_removing_ = false;
206 event_->Signal(); 259 event_->Signal();
207 } 260 }
208 261
209 scoped_ptr<base::WaitableEvent> event_; 262 scoped_ptr<base::WaitableEvent> event_;
210 // The point in time when we start removing data. 263 // The point in time when we start removing data.
211 base::Time remove_start_time_; 264 base::Time remove_start_time_;
212 // The point in time from which on we remove data. 265 // The point in time from which on we remove data.
213 base::Time begin_time_; 266 base::Time begin_time_;
214 bool is_removing_; 267 bool is_removing_;
215 268
216 // The resource context for the profile. 269 // Path for the current profile. Must be retrieved on the UI thread from the
217 content::ResourceContext* resource_context_; 270 // browser context when we start so we can use it later on the I/O thread.
271 FilePath browser_context_path_;
272
273 // The resource context for the profile. Use only on the I/O thread.
274 ResourceContext* resource_context_;
218 275
219 // The channel is NULL until we have opened a connection to the plug-in 276 // The channel is NULL until we have opened a connection to the plug-in
220 // process. 277 // process.
221 scoped_ptr<IPC::Channel> channel_; 278 scoped_ptr<IPC::Channel> channel_;
222 }; 279 };
223 280
224 281
225 PluginDataRemoverImpl::PluginDataRemoverImpl( 282 PluginDataRemoverImpl::PluginDataRemoverImpl(BrowserContext* browser_context)
226 content::ResourceContext* resource_context)
227 : mime_type_(kFlashMimeType), 283 : mime_type_(kFlashMimeType),
228 resource_context_(resource_context) { 284 browser_context_(browser_context) {
229 } 285 }
230 286
231 PluginDataRemoverImpl::~PluginDataRemoverImpl() { 287 PluginDataRemoverImpl::~PluginDataRemoverImpl() {
232 } 288 }
233 289
234 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( 290 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving(
235 base::Time begin_time) { 291 base::Time begin_time) {
236 DCHECK(!context_.get()); 292 DCHECK(!context_.get());
237 context_ = new Context(begin_time, resource_context_); 293 context_ = new Context(begin_time, browser_context_);
238 context_->Init(mime_type_); 294 context_->Init(mime_type_);
239 return context_->event(); 295 return context_->event();
240 } 296 }
297
298 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/plugin_data_remover_impl.h ('k') | content/browser/plugin_data_remover_impl_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698