OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/message_loop_proxy.h" | 7 #include "base/message_loop_proxy.h" |
| 8 #include "base/metrics/histogram.h" |
| 9 #include "base/version.h" |
8 #include "chrome/browser/browser_thread.h" | 10 #include "chrome/browser/browser_thread.h" |
9 #include "chrome/browser/plugin_service.h" | 11 #include "chrome/browser/plugin_service.h" |
10 #include "chrome/common/plugin_messages.h" | 12 #include "chrome/common/plugin_messages.h" |
11 #include "ipc/ipc_channel.h" | 13 #include "webkit/glue/plugins/plugin_group.h" |
| 14 #include "webkit/glue/plugins/plugin_list.h" |
12 | 15 |
13 #if defined(OS_POSIX) | 16 #if defined(OS_POSIX) |
14 #include "ipc/ipc_channel_posix.h" | 17 #include "ipc/ipc_channel_posix.h" |
15 #endif | 18 #endif |
16 | 19 |
17 namespace { | 20 namespace { |
18 const std::string flash_mime_type = "application/x-shockwave-flash"; | 21 const char* g_flash_mime_type = "application/x-shockwave-flash"; |
19 const int64 timeout_ms = 10000; | 22 // TODO(bauerb): Update minimum required Flash version as soon as there is one |
20 } | 23 // implementing the API. |
| 24 const char* g_min_flash_version = "100"; |
| 25 const int64 g_timeout_ms = 10000; |
| 26 } // namespace |
21 | 27 |
22 PluginDataRemover::PluginDataRemover() | 28 PluginDataRemover::PluginDataRemover() |
23 : channel_(NULL), | 29 : is_removing_(false), |
24 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 30 channel_(NULL) { } |
25 } | |
26 | 31 |
27 PluginDataRemover::~PluginDataRemover() { | 32 PluginDataRemover::~PluginDataRemover() { |
28 DCHECK(!done_task_.get()); | 33 DCHECK(!is_removing_); |
29 if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_)) | 34 if (channel_) |
30 delete channel_; | 35 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); |
31 } | 36 } |
32 | 37 |
33 void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) { | 38 void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) { |
34 DCHECK(!done_task_.get()); | 39 DCHECK(!done_task_.get()); |
| 40 DCHECK(!is_removing_); |
| 41 remove_start_time_ = base::Time::Now(); |
35 begin_time_ = begin_time; | 42 begin_time_ = begin_time; |
36 | 43 |
37 message_loop_ = base::MessageLoopProxy::CreateForCurrentThread(); | 44 message_loop_ = base::MessageLoopProxy::CreateForCurrentThread(); |
38 done_task_.reset(done_task); | 45 done_task_.reset(done_task); |
| 46 is_removing_ = true; |
39 | 47 |
| 48 AddRef(); |
40 PluginService::GetInstance()->OpenChannelToPlugin( | 49 PluginService::GetInstance()->OpenChannelToPlugin( |
41 GURL(), flash_mime_type, this); | 50 GURL(), g_flash_mime_type, this); |
42 | 51 |
43 BrowserThread::PostDelayedTask( | 52 BrowserThread::PostDelayedTask( |
44 BrowserThread::IO, | 53 BrowserThread::IO, |
45 FROM_HERE, | 54 FROM_HERE, |
46 method_factory_.NewRunnableMethod(&PluginDataRemover::OnTimeout), | 55 NewRunnableMethod(this, &PluginDataRemover::OnTimeout), |
47 timeout_ms); | 56 g_timeout_ms); |
48 } | 57 } |
49 | 58 |
50 int PluginDataRemover::ID() { | 59 int PluginDataRemover::ID() { |
51 // Generate an ID for the browser process. | 60 // Generate an ID for the browser process. |
52 return ChildProcessInfo::GenerateChildProcessUniqueId(); | 61 return ChildProcessInfo::GenerateChildProcessUniqueId(); |
53 } | 62 } |
54 | 63 |
55 bool PluginDataRemover::OffTheRecord() { | 64 bool PluginDataRemover::OffTheRecord() { |
56 return false; | 65 return false; |
57 } | 66 } |
58 | 67 |
59 void PluginDataRemover::SetPluginInfo(const WebPluginInfo& info) { | 68 void PluginDataRemover::SetPluginInfo(const WebPluginInfo& info) { |
60 } | 69 } |
61 | 70 |
62 void PluginDataRemover::OnChannelOpened(const IPC::ChannelHandle& handle) { | 71 void PluginDataRemover::OnChannelOpened(const IPC::ChannelHandle& handle) { |
| 72 ConnectToChannel(handle); |
| 73 Release(); |
| 74 } |
| 75 |
| 76 void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) { |
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 78 |
| 79 // If we timed out, don't bother connecting. |
| 80 if (!is_removing_) |
| 81 return; |
| 82 |
64 DCHECK(!channel_); | 83 DCHECK(!channel_); |
65 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); | 84 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); |
66 if (!channel_->Connect()) { | 85 if (!channel_->Connect()) { |
67 NOTREACHED() << "Couldn't connect to plugin"; | 86 LOG(DFATAL) << "Couldn't connect to plugin"; |
68 SignalDone(); | 87 SignalDone(); |
69 return; | 88 return; |
70 } | 89 } |
71 | 90 |
72 if (!channel_->Send( | 91 if (!channel_->Send( |
73 new PluginMsg_ClearSiteData(0, std::string(), begin_time_))) { | 92 new PluginMsg_ClearSiteData(0, std::string(), begin_time_))) { |
74 NOTREACHED() << "Couldn't send ClearSiteData message"; | 93 LOG(DFATAL) << "Couldn't send ClearSiteData message"; |
75 SignalDone(); | 94 SignalDone(); |
76 } | 95 } |
77 } | 96 } |
78 | 97 |
79 void PluginDataRemover::OnError() { | 98 void PluginDataRemover::OnError() { |
80 NOTREACHED() << "Couldn't open plugin channel"; | 99 NOTREACHED() << "Couldn't open plugin channel"; |
81 SignalDone(); | 100 SignalDone(); |
| 101 Release(); |
82 } | 102 } |
83 | 103 |
84 void PluginDataRemover::OnClearSiteDataResult(bool success) { | 104 void PluginDataRemover::OnClearSiteDataResult(bool success) { |
85 DCHECK(success) << "ClearSiteData returned error"; | 105 if (!success) |
| 106 LOG(DFATAL) << "ClearSiteData returned error"; |
| 107 UMA_HISTOGRAM_TIMES("ClearPluginData.time", |
| 108 base::Time::Now() - remove_start_time_); |
86 SignalDone(); | 109 SignalDone(); |
87 } | 110 } |
88 | 111 |
89 void PluginDataRemover::OnTimeout() { | 112 void PluginDataRemover::OnTimeout() { |
90 NOTREACHED() << "Timed out"; | 113 NOTREACHED() << "Timed out"; |
91 SignalDone(); | 114 SignalDone(); |
92 } | 115 } |
93 | 116 |
94 void PluginDataRemover::OnMessageReceived(const IPC::Message& msg) { | 117 void PluginDataRemover::OnMessageReceived(const IPC::Message& msg) { |
95 IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg) | 118 IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg) |
96 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, | 119 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, |
97 OnClearSiteDataResult) | 120 OnClearSiteDataResult) |
98 IPC_MESSAGE_UNHANDLED_ERROR() | 121 IPC_MESSAGE_UNHANDLED_ERROR() |
99 IPC_END_MESSAGE_MAP() | 122 IPC_END_MESSAGE_MAP() |
100 } | 123 } |
101 | 124 |
102 void PluginDataRemover::OnChannelError() { | 125 void PluginDataRemover::OnChannelError() { |
103 NOTREACHED() << "Channel error"; | 126 LOG(DFATAL) << "Channel error"; |
104 SignalDone(); | 127 SignalDone(); |
105 } | 128 } |
106 | 129 |
107 void PluginDataRemover::SignalDone() { | 130 void PluginDataRemover::SignalDone() { |
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
109 if (!done_task_.get()) | 132 if (!is_removing_) |
110 return; | 133 return; |
111 message_loop_->PostTask(FROM_HERE, done_task_.release()); | 134 is_removing_ = false; |
112 message_loop_ = NULL; | 135 if (done_task_.get()) { |
| 136 message_loop_->PostTask(FROM_HERE, done_task_.release()); |
| 137 message_loop_ = NULL; |
| 138 } |
113 } | 139 } |
| 140 |
| 141 // static |
| 142 bool PluginDataRemover::IsSupported() { |
| 143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 144 bool allow_wildcard = false; |
| 145 WebPluginInfo plugin; |
| 146 std::string mime_type; |
| 147 if (!NPAPI::PluginList::Singleton()->GetPluginInfo(GURL(), |
| 148 g_flash_mime_type, |
| 149 allow_wildcard, |
| 150 &plugin, |
| 151 &mime_type)) |
| 152 return false; |
| 153 scoped_ptr<Version> version( |
| 154 PluginGroup::CreateVersionFromString(plugin.version)); |
| 155 scoped_ptr<Version> min_version( |
| 156 Version::GetVersionFromString(g_min_flash_version)); |
| 157 return plugin.enabled && |
| 158 version.get() && |
| 159 min_version->CompareTo(*version) == -1; |
| 160 } |
OLD | NEW |