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 "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" |
11 #include "content/browser/plugin_process_host.h" | 11 #include "content/browser/plugin_process_host.h" |
12 #include "content/browser/plugin_service_impl.h" | 12 #include "content/browser/plugin_service_impl.h" |
13 #include "content/common/child_process_host_impl.h" | 13 #include "content/common/child_process_host_impl.h" |
14 #include "content/common/plugin_messages.h" | 14 #include "content/common/plugin_messages.h" |
15 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
16 #include "content/public/common/pepper_plugin_info.h" | |
17 #include "ppapi/proxy/ppapi_messages.h" | |
16 #include "webkit/plugins/npapi/plugin_group.h" | 18 #include "webkit/plugins/npapi/plugin_group.h" |
17 | 19 |
18 using content::BrowserThread; | 20 using content::BrowserThread; |
19 using content::ChildProcessHostImpl; | 21 using content::ChildProcessHostImpl; |
20 | 22 |
21 namespace { | 23 namespace { |
22 | 24 |
23 const char kFlashMimeType[] = "application/x-shockwave-flash"; | 25 const char kFlashMimeType[] = "application/x-shockwave-flash"; |
24 // The minimum Flash Player version that implements NPP_ClearSiteData. | 26 // The minimum Flash Player version that implements NPP_ClearSiteData. |
25 const char kMinFlashVersion[] = "10.3"; | 27 const char kMinFlashVersion[] = "10.3"; |
(...skipping 22 matching lines...) Expand all Loading... | |
48 scoped_ptr<Version> version( | 50 scoped_ptr<Version> version( |
49 webkit::npapi::PluginGroup::CreateVersionFromString(plugin_it->version)); | 51 webkit::npapi::PluginGroup::CreateVersionFromString(plugin_it->version)); |
50 scoped_ptr<Version> min_version( | 52 scoped_ptr<Version> min_version( |
51 Version::GetVersionFromString(kMinFlashVersion)); | 53 Version::GetVersionFromString(kMinFlashVersion)); |
52 bool rv = version.get() && min_version->CompareTo(*version) == -1; | 54 bool rv = version.get() && min_version->CompareTo(*version) == -1; |
53 if (rv) | 55 if (rv) |
54 *plugin = *plugin_it; | 56 *plugin = *plugin_it; |
55 return rv; | 57 return rv; |
56 } | 58 } |
57 | 59 |
58 } | 60 } // namespace content |
59 | 61 |
60 class PluginDataRemoverImpl::Context | 62 class PluginDataRemoverImpl::Context |
61 : public PluginProcessHost::Client, | 63 : public PluginProcessHost::Client, |
64 public PpapiPluginProcessHost::BrokerClient, | |
62 public IPC::Channel::Listener, | 65 public IPC::Channel::Listener, |
63 public base::RefCountedThreadSafe<Context, | 66 public base::RefCountedThreadSafe<Context, |
64 BrowserThread::DeleteOnIOThread> { | 67 BrowserThread::DeleteOnIOThread> { |
65 public: | 68 public: |
66 Context(base::Time begin_time, | 69 Context(base::Time begin_time, |
67 content::ResourceContext* resource_context) | 70 content::ResourceContext* resource_context) |
68 : event_(new base::WaitableEvent(true, false)), | 71 : event_(new base::WaitableEvent(true, false)), |
69 begin_time_(begin_time), | 72 begin_time_(begin_time), |
70 is_removing_(false), | 73 is_removing_(false), |
71 resource_context_(resource_context), | 74 resource_context_(resource_context), |
72 channel_(NULL) { | 75 channel_(NULL) { |
73 } | 76 } |
74 | 77 |
75 virtual ~Context() { | 78 virtual ~Context() { |
76 } | 79 } |
77 | 80 |
78 void Init(const std::string& mime_type) { | 81 void Init(const std::string& mime_type) { |
79 BrowserThread::PostTask( | 82 BrowserThread::PostTask( |
80 BrowserThread::IO, | 83 BrowserThread::IO, |
81 FROM_HERE, | 84 FROM_HERE, |
82 base::Bind(&Context::InitOnIOThread, this, mime_type)); | 85 base::Bind(&Context::InitOnIOThread, this, mime_type)); |
83 BrowserThread::PostDelayedTask( | 86 BrowserThread::PostDelayedTask( |
84 BrowserThread::IO, | 87 BrowserThread::IO, |
85 FROM_HERE, | 88 FROM_HERE, |
86 base::Bind(&Context::OnTimeout, this), | 89 base::Bind(&Context::OnTimeout, this), |
87 base::TimeDelta::FromMilliseconds(kRemovalTimeoutMs)); | 90 base::TimeDelta::FromMilliseconds(kRemovalTimeoutMs)); |
88 } | 91 } |
89 | 92 |
90 // Initialize on the IO thread. | |
91 void InitOnIOThread(const std::string& mime_type) { | 93 void InitOnIOThread(const std::string& mime_type) { |
94 PluginServiceImpl* plugin_service = PluginServiceImpl::GetInstance(); | |
95 | |
96 // Get the plugin file path. | |
97 std::vector<webkit::WebPluginInfo> plugins; | |
98 plugin_service->GetPluginInfoArray( | |
99 GURL(), mime_type, false, &plugins, NULL); | |
100 if (plugins.empty()) { | |
101 NOTREACHED(); | |
102 return; | |
103 } | |
104 FilePath plugin_path = plugins[0].path; | |
105 | |
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
93 remove_start_time_ = base::Time::Now(); | 107 remove_start_time_ = base::Time::Now(); |
94 is_removing_ = true; | 108 is_removing_ = true; |
95 // Balanced in OnChannelOpened or OnError. Exactly one them will eventually | 109 // Balanced in OnChannelOpened or OnError. Exactly one them will eventually |
96 // be called, so we need to keep this object around until then. | 110 // be called, so we need to keep this object around until then. |
97 AddRef(); | 111 AddRef(); |
98 PluginServiceImpl::GetInstance()->OpenChannelToNpapiPlugin( | 112 |
99 0, 0, GURL(), GURL(), mime_type, this); | 113 content::PepperPluginInfo* pepper_info = |
114 plugin_service->GetRegisteredPpapiPluginInfo(plugin_path); | |
115 if (pepper_info) { | |
116 // Use the broker since we run this function outside the sandbox. | |
117 plugin_service->OpenChannelToPpapiBroker(plugin_path, this); | |
118 } else { | |
119 plugin_service->OpenChannelToNpapiPlugin( | |
120 0, 0, GURL(), GURL(), mime_type, this); | |
121 } | |
100 } | 122 } |
101 | 123 |
102 // Called when a timeout happens in order not to block the client | 124 // Called when a timeout happens in order not to block the client |
103 // indefinitely. | 125 // indefinitely. |
104 void OnTimeout() { | 126 void OnTimeout() { |
105 LOG_IF(ERROR, is_removing_) << "Timed out"; | 127 LOG_IF(ERROR, is_removing_) << "Timed out"; |
106 SignalDone(); | 128 SignalDone(); |
107 } | 129 } |
108 | 130 |
109 // PluginProcessHost::Client methods. | 131 // PluginProcessHost::Client methods. |
(...skipping 13 matching lines...) Expand all Loading... | |
123 virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE { | 145 virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE { |
124 } | 146 } |
125 | 147 |
126 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE { | 148 virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE { |
127 } | 149 } |
128 | 150 |
129 virtual void OnSentPluginChannelRequest() OVERRIDE { | 151 virtual void OnSentPluginChannelRequest() OVERRIDE { |
130 } | 152 } |
131 | 153 |
132 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE { | 154 virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE { |
133 ConnectToChannel(handle); | 155 ConnectToChannel(handle, false); |
134 // Balancing the AddRef call. | 156 // Balancing the AddRef call. |
135 Release(); | 157 Release(); |
136 } | 158 } |
137 | 159 |
138 virtual void OnError() OVERRIDE { | 160 virtual void OnError() OVERRIDE { |
139 LOG(ERROR) << "Couldn't open plugin channel"; | 161 LOG(ERROR) << "Couldn't open plugin channel"; |
140 SignalDone(); | 162 SignalDone(); |
141 // Balancing the AddRef call. | 163 // Balancing the AddRef call. |
142 Release(); | 164 Release(); |
143 } | 165 } |
144 | 166 |
167 // PpapiPluginProcessHost::BrokerClient implementation. | |
168 virtual void GetChannelInfo(base::ProcessHandle* renderer_handle, | |
169 int* renderer_id) OVERRIDE { | |
170 *renderer_id = 0; | |
171 } | |
172 | |
173 virtual void OnChannelOpened( | |
174 base::ProcessHandle plugin_process_handle, | |
175 const IPC::ChannelHandle& channel_handle) OVERRIDE { | |
176 ConnectToChannel(channel_handle, true); | |
177 // Balancing the AddRef call. | |
178 Release(); | |
179 } | |
180 | |
145 // IPC::Channel::Listener methods. | 181 // IPC::Channel::Listener methods. |
146 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 182 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
147 IPC_BEGIN_MESSAGE_MAP(Context, message) | 183 IPC_BEGIN_MESSAGE_MAP(Context, message) |
148 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, | 184 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, |
149 OnClearSiteDataResult) | 185 OnClearSiteDataResult) |
186 IPC_MESSAGE_HANDLER(PpapiHostMsg_ClearSiteDataResult, | |
187 OnClearSiteDataResult) | |
150 IPC_MESSAGE_UNHANDLED_ERROR() | 188 IPC_MESSAGE_UNHANDLED_ERROR() |
151 IPC_END_MESSAGE_MAP() | 189 IPC_END_MESSAGE_MAP() |
152 | 190 |
153 return true; | 191 return true; |
154 } | 192 } |
155 | 193 |
156 virtual void OnChannelError() OVERRIDE { | 194 virtual void OnChannelError() OVERRIDE { |
157 if (is_removing_) { | 195 if (is_removing_) { |
158 NOTREACHED() << "Channel error"; | 196 NOTREACHED() << "Channel error"; |
159 SignalDone(); | 197 SignalDone(); |
160 } | 198 } |
161 } | 199 } |
162 | 200 |
163 base::WaitableEvent* event() { return event_.get(); } | 201 base::WaitableEvent* event() { return event_.get(); } |
164 | 202 |
165 private: | 203 private: |
166 // Connects the client side of a newly opened plug-in channel. | 204 // Connects the client side of a newly opened plug-in channel. |
167 void ConnectToChannel(const IPC::ChannelHandle& handle) { | 205 void ConnectToChannel(const IPC::ChannelHandle& handle, bool is_ppapi) { |
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
169 | 207 |
170 // If we timed out, don't bother connecting. | 208 // If we timed out, don't bother connecting. |
171 if (!is_removing_) | 209 if (!is_removing_) |
172 return; | 210 return; |
173 | 211 |
174 DCHECK(!channel_.get()); | 212 DCHECK(!channel_.get()); |
175 channel_.reset(new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this)); | 213 channel_.reset(new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this)); |
176 if (!channel_->Connect()) { | 214 if (!channel_->Connect()) { |
177 NOTREACHED() << "Couldn't connect to plugin"; | 215 NOTREACHED() << "Couldn't connect to plugin"; |
178 SignalDone(); | 216 SignalDone(); |
179 return; | 217 return; |
180 } | 218 } |
181 | 219 |
182 if (!channel_->Send(new PluginMsg_ClearSiteData(std::string(), | 220 uint64 max_age = begin_time_.is_null() ? |
183 kClearAllData, | 221 std::numeric_limits<uint64>::max() : |
184 begin_time_))) { | 222 (base::Time::Now() - begin_time_).InSeconds(); |
223 | |
224 IPC::Message* msg; | |
225 if (is_ppapi) { | |
226 FilePath profile_path; // FIXME ========================================= =============== | |
Bernhard Bauer
2012/04/10 20:13:44
Can you make this a TODO?
| |
227 msg = new PpapiMsg_ClearSiteData(profile_path, std::string(), | |
228 kClearAllData, max_age); | |
229 } else { | |
230 msg = new PluginMsg_ClearSiteData(std::string(), kClearAllData, max_age); | |
231 } | |
232 if (!channel_->Send(msg)) { | |
185 NOTREACHED() << "Couldn't send ClearSiteData message"; | 233 NOTREACHED() << "Couldn't send ClearSiteData message"; |
186 SignalDone(); | 234 SignalDone(); |
187 return; | 235 return; |
188 } | 236 } |
189 } | 237 } |
190 | 238 |
191 // Handles the PluginHostMsg_ClearSiteDataResult message. | 239 // Handles the *HostMsg_ClearSiteDataResult message. |
192 void OnClearSiteDataResult(bool success) { | 240 void OnClearSiteDataResult(bool success) { |
193 LOG_IF(ERROR, !success) << "ClearSiteData returned error"; | 241 LOG_IF(ERROR, !success) << "ClearSiteData returned error"; |
194 UMA_HISTOGRAM_TIMES("ClearPluginData.time", | 242 UMA_HISTOGRAM_TIMES("ClearPluginData.time", |
195 base::Time::Now() - remove_start_time_); | 243 base::Time::Now() - remove_start_time_); |
196 SignalDone(); | 244 SignalDone(); |
197 } | 245 } |
198 | 246 |
199 // Signals that we are finished with removing data (successful or not). This | 247 // Signals that we are finished with removing data (successful or not). This |
200 // method is safe to call multiple times. | 248 // method is safe to call multiple times. |
201 void SignalDone() { | 249 void SignalDone() { |
(...skipping 29 matching lines...) Expand all Loading... | |
231 PluginDataRemoverImpl::~PluginDataRemoverImpl() { | 279 PluginDataRemoverImpl::~PluginDataRemoverImpl() { |
232 } | 280 } |
233 | 281 |
234 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( | 282 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( |
235 base::Time begin_time) { | 283 base::Time begin_time) { |
236 DCHECK(!context_.get()); | 284 DCHECK(!context_.get()); |
237 context_ = new Context(begin_time, resource_context_); | 285 context_ = new Context(begin_time, resource_context_); |
238 context_->Init(mime_type_); | 286 context_->Init(mime_type_); |
239 return context_->event(); | 287 return context_->event(); |
240 } | 288 } |
OLD | NEW |