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

Side by Side Diff: chrome/browser/plugin_finder.cc

Issue 10933044: Move chrome/browser/plugin_* to chrome/browser/plugins/ (Closed) Base URL: http://git.chromium.org/chromium/src.git@remove_plugin_group
Patch Set: . Created 8 years, 3 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
« no previous file with comments | « chrome/browser/plugin_finder.h ('k') | chrome/browser/plugin_finder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/plugin_finder.h"
6
7 #include "base/bind.h"
8 #include "base/json/json_reader.h"
9 #include "base/message_loop.h"
10 #include "base/stl_util.h"
11 #include "base/sys_string_conversions.h"
12 #include "base/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/plugin_installer.h"
16 #include "chrome/browser/prefs/pref_service.h"
17 #include "chrome/common/pref_names.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/plugin_service.h"
20 #include "googleurl/src/gurl.h"
21 #include "grit/browser_resources.h"
22 #include "ui/base/layout.h"
23 #include "ui/base/resource/resource_bundle.h"
24
25 using base::DictionaryValue;
26 using content::PluginService;
27
28 namespace {
29
30 // Gets the base name of the file path as the identifier.
31 static std::string GetIdentifier(const webkit::WebPluginInfo& plugin) {
32 #if defined(OS_POSIX)
33 return plugin.path.BaseName().value();
34 #elif defined(OS_WIN)
35 return base::SysWideToUTF8(plugin.path.BaseName().value());
36 #endif
37 }
38
39 // Gets the plug-in group name as the plug-in name if it is not empty or
40 // the filename without extension if the name is empty.
41 static string16 GetGroupName(const webkit::WebPluginInfo& plugin) {
42 if (!plugin.name.empty())
43 return plugin.name;
44
45 FilePath::StringType path = plugin.path.BaseName().RemoveExtension().value();
46 #if defined(OS_POSIX)
47 return UTF8ToUTF16(path);
48 #elif defined(OS_WIN)
49 return WideToUTF16(path);
50 #endif
51 }
52
53 // A callback barrier used to enforce the execution of a callback function
54 // only when two different asynchronous callbacks are done execution.
55 // The first asynchronous callback gets a PluginFinder instance and the
56 // second asynchronous callback gets a list of plugins.
57 class PluginFinderCallbackBarrier
58 : public base::RefCountedThreadSafe<PluginFinderCallbackBarrier> {
59 public:
60 typedef base::Callback<void(const PluginFinder::PluginVector&)>
61 PluginsCallback;
62
63 explicit PluginFinderCallbackBarrier(
64 const PluginFinder::CombinedCallback& callback)
65 : callback_(callback),
66 finder_(NULL) {
67 DCHECK(!callback_.is_null());
68 }
69
70 base::Callback<void(PluginFinder*)> CreatePluginFinderCallback() {
71 return base::Bind(&PluginFinderCallbackBarrier::GotPluginFinder, this);
72 }
73
74 PluginsCallback CreatePluginsCallback() {
75 return base::Bind(&PluginFinderCallbackBarrier::GotPlugins, this);
76 }
77
78 private:
79 friend class base::RefCountedThreadSafe<PluginFinderCallbackBarrier>;
80
81 ~PluginFinderCallbackBarrier() {
82 DCHECK(callback_.is_null());
83 }
84
85 void GotPlugins(const PluginFinder::PluginVector& plugins) {
86 plugins_.reset(new PluginFinder::PluginVector(plugins));
87 MaybeRunCallback();
88 }
89
90 void GotPluginFinder(PluginFinder* finder) {
91 finder_ = finder;
92 MaybeRunCallback();
93 }
94
95 // Executes the callback only when both asynchronous methods have finished
96 // their executions. This is identified by having non-null values in both
97 // |finder_| and |plugins_|.
98 void MaybeRunCallback() {
99 if (!finder_ || !plugins_.get())
100 return;
101
102 callback_.Run(*plugins_, finder_);
103 callback_.Reset();
104 }
105
106 PluginFinder::CombinedCallback callback_;
107 PluginFinder* finder_;
108 scoped_ptr<PluginFinder::PluginVector> plugins_;
109 };
110
111 } // namespace
112
113 // static
114 void PluginFinder::GetPluginsAndPluginFinder(
115 const PluginFinder::CombinedCallback& cb) {
116 scoped_refptr<PluginFinderCallbackBarrier> barrier =
117 new PluginFinderCallbackBarrier(cb);
118
119 PluginFinder::Get(barrier->CreatePluginFinderCallback());
120 PluginService::GetInstance()->GetPlugins(barrier->CreatePluginsCallback());
121 }
122
123 // static
124 void PluginFinder::Get(const base::Callback<void(PluginFinder*)>& cb) {
125 // At a later point we might want to do intialization here that needs to be
126 // done asynchronously, like loading the plug-in list from disk or from a URL.
127 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(cb, GetInstance()));
128 }
129
130 // static
131 PluginFinder* PluginFinder::GetInstance() {
132 // PluginFinder::GetInstance() is the only method that's allowed to call
133 // Singleton<PluginFinder>::get().
134 return Singleton<PluginFinder>::get();
135 }
136
137 PluginFinder::PluginFinder() : plugin_list_(LoadPluginList()) {
138 if (!plugin_list_.get())
139 plugin_list_.reset(new DictionaryValue());
140 }
141
142 // static
143 DictionaryValue* PluginFinder::LoadPluginList() {
144 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
145 base::StringPiece json_resource(
146 ResourceBundle::GetSharedInstance().GetRawDataResource(
147 IDR_PLUGIN_DB_JSON, ui::SCALE_FACTOR_NONE));
148 std::string error_str;
149 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
150 json_resource,
151 base::JSON_PARSE_RFC,
152 NULL,
153 &error_str));
154 if (!value.get()) {
155 DLOG(ERROR) << error_str;
156 return NULL;
157 }
158 if (value->GetType() != base::Value::TYPE_DICTIONARY)
159 return NULL;
160 return static_cast<base::DictionaryValue*>(value.release());
161 #else
162 return new DictionaryValue();
163 #endif
164 }
165
166 PluginFinder::~PluginFinder() {
167 STLDeleteValues(&installers_);
168 }
169
170 PluginInstaller* PluginFinder::FindPlugin(const std::string& mime_type,
171 const std::string& language) {
172 if (g_browser_process->local_state()->GetBoolean(prefs::kDisablePluginFinder))
173 return NULL;
174 for (DictionaryValue::Iterator plugin_it(*plugin_list_);
175 plugin_it.HasNext(); plugin_it.Advance()) {
176 const DictionaryValue* plugin = NULL;
177 if (!plugin_it.value().GetAsDictionary(&plugin)) {
178 NOTREACHED();
179 continue;
180 }
181 std::string language_str;
182 bool success = plugin->GetString("lang", &language_str);
183 if (language_str != language)
184 continue;
185 const ListValue* mime_types = NULL;
186 plugin->GetList("mime_types", &mime_types);
187 DCHECK(success);
188 for (ListValue::const_iterator mime_type_it = mime_types->begin();
189 mime_type_it != mime_types->end(); ++mime_type_it) {
190 std::string mime_type_str;
191 success = (*mime_type_it)->GetAsString(&mime_type_str);
192 DCHECK(success);
193 if (mime_type_str == mime_type) {
194 std::string identifier = plugin_it.key();
195 std::map<std::string, PluginInstaller*>::const_iterator installer =
196 installers_.find(identifier);
197 if (installer != installers_.end())
198 return installer->second;
199 return CreateInstaller(identifier, plugin);
200 }
201 }
202 }
203 return NULL;
204 }
205
206 PluginInstaller* PluginFinder::FindPluginWithIdentifier(
207 const std::string& identifier) {
208 std::map<std::string, PluginInstaller*>::const_iterator it =
209 installers_.find(identifier);
210 if (it != installers_.end())
211 return it->second;
212 DictionaryValue* plugin = NULL;
213 if (plugin_list_->GetDictionaryWithoutPathExpansion(identifier, &plugin))
214 return CreateInstaller(identifier, plugin);
215 return NULL;
216 }
217
218 PluginInstaller* PluginFinder::CreateInstaller(
219 const std::string& identifier,
220 const DictionaryValue* plugin_dict) {
221 DCHECK(!installers_[identifier]);
222 std::string url;
223 bool success = plugin_dict->GetString("url", &url);
224 std::string help_url;
225 plugin_dict->GetString("help_url", &help_url);
226 string16 name;
227 success = plugin_dict->GetString("name", &name);
228 DCHECK(success);
229 bool display_url = false;
230 plugin_dict->GetBoolean("displayurl", &display_url);
231 string16 group_name_matcher;
232 success = plugin_dict->GetString("group_name_matcher", &group_name_matcher);
233 DCHECK(success);
234
235 PluginInstaller* installer = new PluginInstaller(identifier,
236 name,
237 display_url,
238 GURL(url),
239 GURL(help_url),
240 group_name_matcher);
241 const ListValue* versions = NULL;
242 if (plugin_dict->GetList("versions", &versions)) {
243 for (ListValue::const_iterator it = versions->begin();
244 it != versions->end(); ++it) {
245 DictionaryValue* version_dict = NULL;
246 if (!(*it)->GetAsDictionary(&version_dict)) {
247 NOTREACHED();
248 continue;
249 }
250 std::string version;
251 success = version_dict->GetString("version", &version);
252 DCHECK(success);
253 std::string status_str;
254 success = version_dict->GetString("status", &status_str);
255 DCHECK(success);
256 PluginInstaller::SecurityStatus status =
257 PluginInstaller::SECURITY_STATUS_UP_TO_DATE;
258 success = PluginInstaller::ParseSecurityStatus(status_str, &status);
259 DCHECK(success);
260 installer->AddVersion(Version(version), status);
261 }
262 }
263
264 installers_[identifier] = installer;
265 return installer;
266 }
267
268 PluginInstaller* PluginFinder::GetPluginInstaller(
269 const webkit::WebPluginInfo& plugin) {
270 if (name_installers_.find(plugin.name) != name_installers_.end())
271 return name_installers_[plugin.name];
272
273 for (DictionaryValue::Iterator plugin_it(*plugin_list_);
274 plugin_it.HasNext(); plugin_it.Advance()) {
275 // This method triggers the lazy initialization for all PluginInstallers.
276 FindPluginWithIdentifier(plugin_it.key());
277 }
278
279 // Use the group name matcher to find the plug-in installer we want.
280 for (std::map<std::string, PluginInstaller*>::const_iterator it =
281 installers_.begin(); it != installers_.end(); ++it) {
282 if (!it->second->MatchesPlugin(plugin))
283 continue;
284
285 name_installers_[plugin.name] = it->second;
286 return it->second;
287 }
288
289 // The plug-in installer was not found, create a dummy one holding
290 // the name, identifier and group name only.
291 std::string identifier = GetIdentifier(plugin);
292 PluginInstaller* installer = new PluginInstaller(identifier,
293 GetGroupName(plugin),
294 false, GURL(), GURL(),
295 GetGroupName(plugin));
296 installers_[identifier] = installer;
297 name_installers_[plugin.name] = installer;
298 return installer;
299 }
OLDNEW
« no previous file with comments | « chrome/browser/plugin_finder.h ('k') | chrome/browser/plugin_finder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698