OLD | NEW |
1 // Copyright (c) 2010 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 "chrome/browser/plugin_data_remover.h" | 5 #include "chrome/browser/plugin_data_remover.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/version.h" | 10 #include "base/version.h" |
11 #include "chrome/browser/browser_thread.h" | 11 #include "chrome/browser/browser_thread.h" |
(...skipping 10 matching lines...) Expand all Loading... |
22 namespace { | 22 namespace { |
23 const char* kFlashMimeType = "application/x-shockwave-flash"; | 23 const char* kFlashMimeType = "application/x-shockwave-flash"; |
24 // TODO(bauerb): Update minimum required Flash version as soon as there is one | 24 // TODO(bauerb): Update minimum required Flash version as soon as there is one |
25 // implementing the API. | 25 // implementing the API. |
26 const char* kMinFlashVersion = "100"; | 26 const char* kMinFlashVersion = "100"; |
27 const int64 kRemovalTimeoutMs = 10000; | 27 const int64 kRemovalTimeoutMs = 10000; |
28 const uint64 kClearAllData = 0; | 28 const uint64 kClearAllData = 0; |
29 } // namespace | 29 } // namespace |
30 | 30 |
31 PluginDataRemover::PluginDataRemover() | 31 PluginDataRemover::PluginDataRemover() |
32 : is_removing_(false), | 32 : mime_type_(kFlashMimeType), |
| 33 is_removing_(false), |
| 34 event_(new base::WaitableEvent(true, false)), |
33 channel_(NULL) { } | 35 channel_(NULL) { } |
34 | 36 |
35 PluginDataRemover::~PluginDataRemover() { | 37 PluginDataRemover::~PluginDataRemover() { |
36 DCHECK(!is_removing_); | 38 DCHECK(!is_removing_); |
37 if (channel_) | 39 if (channel_) |
38 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); | 40 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); |
39 } | 41 } |
40 | 42 |
41 void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) { | 43 base::WaitableEvent* PluginDataRemover::StartRemoving( |
42 DCHECK(!done_task_.get()); | 44 const base::Time& begin_time) { |
43 DCHECK(!is_removing_); | 45 DCHECK(!is_removing_); |
44 remove_start_time_ = base::Time::Now(); | 46 remove_start_time_ = base::Time::Now(); |
45 begin_time_ = begin_time; | 47 begin_time_ = begin_time; |
46 | 48 |
47 message_loop_ = base::MessageLoopProxy::CreateForCurrentThread(); | |
48 done_task_.reset(done_task); | |
49 is_removing_ = true; | 49 is_removing_ = true; |
50 | 50 |
51 AddRef(); | 51 AddRef(); |
52 PluginService::GetInstance()->OpenChannelToPlugin( | 52 PluginService::GetInstance()->OpenChannelToPlugin( |
53 GURL(), kFlashMimeType, this); | 53 GURL(), mime_type_, this); |
54 | 54 |
55 BrowserThread::PostDelayedTask( | 55 BrowserThread::PostDelayedTask( |
56 BrowserThread::IO, | 56 BrowserThread::IO, |
57 FROM_HERE, | 57 FROM_HERE, |
58 NewRunnableMethod(this, &PluginDataRemover::OnTimeout), | 58 NewRunnableMethod(this, &PluginDataRemover::OnTimeout), |
59 kRemovalTimeoutMs); | 59 kRemovalTimeoutMs); |
| 60 |
| 61 return event_.get(); |
| 62 } |
| 63 |
| 64 void PluginDataRemover::Wait() { |
| 65 base::Time start_time(base::Time::Now()); |
| 66 bool result = true; |
| 67 if (is_removing_) |
| 68 result = event_->Wait(); |
| 69 UMA_HISTOGRAM_TIMES("ClearPluginData.wait_at_shutdown", |
| 70 base::Time::Now() - start_time); |
| 71 UMA_HISTOGRAM_TIMES("ClearPluginData.time_at_shutdown", |
| 72 base::Time::Now() - remove_start_time_); |
| 73 DCHECK(result) << "Error waiting for plugin process"; |
60 } | 74 } |
61 | 75 |
62 int PluginDataRemover::ID() { | 76 int PluginDataRemover::ID() { |
63 // Generate an ID for the browser process. | 77 // Generate an ID for the browser process. |
64 return ChildProcessInfo::GenerateChildProcessUniqueId(); | 78 return ChildProcessInfo::GenerateChildProcessUniqueId(); |
65 } | 79 } |
66 | 80 |
67 bool PluginDataRemover::OffTheRecord() { | 81 bool PluginDataRemover::OffTheRecord() { |
68 return false; | 82 return false; |
69 } | 83 } |
(...skipping 10 matching lines...) Expand all Loading... |
80 void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) { | 94 void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) { |
81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
82 | 96 |
83 // If we timed out, don't bother connecting. | 97 // If we timed out, don't bother connecting. |
84 if (!is_removing_) | 98 if (!is_removing_) |
85 return; | 99 return; |
86 | 100 |
87 DCHECK(!channel_); | 101 DCHECK(!channel_); |
88 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); | 102 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); |
89 if (!channel_->Connect()) { | 103 if (!channel_->Connect()) { |
90 LOG(DFATAL) << "Couldn't connect to plugin"; | 104 NOTREACHED() << "Couldn't connect to plugin"; |
91 SignalDone(); | 105 SignalDone(); |
92 return; | 106 return; |
93 } | 107 } |
94 | 108 |
95 if (!channel_->Send( | 109 if (!channel_->Send( |
96 new PluginMsg_ClearSiteData(std::string(), | 110 new PluginMsg_ClearSiteData(std::string(), |
97 kClearAllData, | 111 kClearAllData, |
98 begin_time_))) { | 112 begin_time_))) { |
99 LOG(DFATAL) << "Couldn't send ClearSiteData message"; | 113 NOTREACHED() << "Couldn't send ClearSiteData message"; |
100 SignalDone(); | 114 SignalDone(); |
| 115 return; |
101 } | 116 } |
102 } | 117 } |
103 | 118 |
104 void PluginDataRemover::OnError() { | 119 void PluginDataRemover::OnError() { |
105 NOTREACHED() << "Couldn't open plugin channel"; | 120 LOG(DFATAL) << "Couldn't open plugin channel"; |
106 SignalDone(); | 121 SignalDone(); |
107 Release(); | 122 Release(); |
108 } | 123 } |
109 | 124 |
110 void PluginDataRemover::OnClearSiteDataResult(bool success) { | 125 void PluginDataRemover::OnClearSiteDataResult(bool success) { |
111 if (!success) | 126 LOG_IF(DFATAL, !success) << "ClearSiteData returned error"; |
112 LOG(DFATAL) << "ClearSiteData returned error"; | |
113 UMA_HISTOGRAM_TIMES("ClearPluginData.time", | 127 UMA_HISTOGRAM_TIMES("ClearPluginData.time", |
114 base::Time::Now() - remove_start_time_); | 128 base::Time::Now() - remove_start_time_); |
115 SignalDone(); | 129 SignalDone(); |
116 } | 130 } |
117 | 131 |
118 void PluginDataRemover::OnTimeout() { | 132 void PluginDataRemover::OnTimeout() { |
119 NOTREACHED() << "Timed out"; | 133 LOG_IF(DFATAL, is_removing_) << "Timed out"; |
120 SignalDone(); | 134 SignalDone(); |
121 } | 135 } |
122 | 136 |
123 bool PluginDataRemover::OnMessageReceived(const IPC::Message& msg) { | 137 bool PluginDataRemover::OnMessageReceived(const IPC::Message& msg) { |
124 IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg) | 138 IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg) |
125 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, | 139 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, |
126 OnClearSiteDataResult) | 140 OnClearSiteDataResult) |
127 IPC_MESSAGE_UNHANDLED_ERROR() | 141 IPC_MESSAGE_UNHANDLED_ERROR() |
128 IPC_END_MESSAGE_MAP() | 142 IPC_END_MESSAGE_MAP() |
129 | 143 |
130 return true; | 144 return true; |
131 } | 145 } |
132 | 146 |
133 void PluginDataRemover::OnChannelError() { | 147 void PluginDataRemover::OnChannelError() { |
134 LOG(DFATAL) << "Channel error"; | 148 if (is_removing_) { |
135 SignalDone(); | 149 NOTREACHED() << "Channel error"; |
| 150 SignalDone(); |
| 151 } |
136 } | 152 } |
137 | 153 |
138 void PluginDataRemover::SignalDone() { | 154 void PluginDataRemover::SignalDone() { |
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
140 if (!is_removing_) | 156 if (!is_removing_) |
141 return; | 157 return; |
142 is_removing_ = false; | 158 is_removing_ = false; |
143 if (done_task_.get()) { | 159 event_->Signal(); |
144 message_loop_->PostTask(FROM_HERE, done_task_.release()); | |
145 message_loop_ = NULL; | |
146 } | |
147 } | 160 } |
148 | 161 |
149 // static | 162 // static |
150 bool PluginDataRemover::IsSupported() { | 163 bool PluginDataRemover::IsSupported() { |
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
152 bool allow_wildcard = false; | 165 bool allow_wildcard = false; |
153 webkit::npapi::WebPluginInfo plugin; | 166 webkit::npapi::WebPluginInfo plugin; |
154 std::string mime_type; | 167 std::string mime_type; |
155 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfo( | 168 if (!webkit::npapi::PluginList::Singleton()->GetPluginInfo( |
156 GURL(), kFlashMimeType, allow_wildcard, &plugin, &mime_type)) { | 169 GURL(), kFlashMimeType, allow_wildcard, &plugin, &mime_type)) { |
157 return false; | 170 return false; |
158 } | 171 } |
159 scoped_ptr<Version> version( | 172 scoped_ptr<Version> version( |
160 webkit::npapi::PluginGroup::CreateVersionFromString(plugin.version)); | 173 webkit::npapi::PluginGroup::CreateVersionFromString(plugin.version)); |
161 scoped_ptr<Version> min_version(Version::GetVersionFromString( | 174 scoped_ptr<Version> min_version(Version::GetVersionFromString( |
162 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 175 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
163 switches::kMinClearSiteDataFlashVersion))); | 176 switches::kMinClearSiteDataFlashVersion))); |
164 if (!min_version.get()) | 177 if (!min_version.get()) |
165 min_version.reset(Version::GetVersionFromString(kMinFlashVersion)); | 178 min_version.reset(Version::GetVersionFromString(kMinFlashVersion)); |
166 return plugin.enabled && | 179 return plugin.enabled && |
167 version.get() && | 180 version.get() && |
168 min_version->CompareTo(*version) == -1; | 181 min_version->CompareTo(*version) == -1; |
169 } | 182 } |
OLD | NEW |