blob: 2e90b5450293574e103bdf6b6c221d2a1e8dfa49 [file] [log] [blame]
[email protected]26193462012-01-05 10:36:551// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]1d697f32011-11-28 11:57:512// 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"
[email protected]f99c87d2011-12-02 02:28:1210#include "base/stl_util.h"
[email protected]1d697f32011-11-28 11:57:5111#include "base/values.h"
12#include "chrome/browser/browser_process.h"
[email protected]f99c87d2011-12-02 02:28:1213#include "chrome/browser/plugin_installer.h"
[email protected]1d697f32011-11-28 11:57:5114#include "chrome/browser/prefs/pref_service.h"
15#include "chrome/common/pref_names.h"
16#include "content/public/browser/browser_thread.h"
17#include "googleurl/src/gurl.h"
18#include "grit/browser_resources.h"
19#include "ui/base/resource/resource_bundle.h"
20
[email protected]26193462012-01-05 10:36:5521// static
[email protected]1d697f32011-11-28 11:57:5122PluginFinder* PluginFinder::GetInstance() {
23 return Singleton<PluginFinder>::get();
24}
25
[email protected]26193462012-01-05 10:36:5526PluginFinder::PluginFinder() : plugin_list_(LoadPluginList()) {
27 if (!plugin_list_.get()) {
28 NOTREACHED();
29 plugin_list_.reset(new base::ListValue());
30 }
31}
32
33// static
34scoped_ptr<base::ListValue> PluginFinder::LoadPluginList() {
35 return scoped_ptr<base::ListValue>(LoadPluginListInternal()).Pass();
36}
37
38base::ListValue* PluginFinder::LoadPluginListInternal() {
[email protected]27c483892012-02-09 15:59:1039#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
[email protected]1d697f32011-11-28 11:57:5140 base::StringPiece json_resource(
41 ResourceBundle::GetSharedInstance().GetRawDataResource(
42 IDR_PLUGIN_DB_JSON));
43 bool allow_trailing_comma = false;
44 std::string error_str;
45 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
46 json_resource.as_string(),
47 allow_trailing_comma,
48 NULL,
49 &error_str));
[email protected]26193462012-01-05 10:36:5550 if (!value.get()) {
51 DLOG(ERROR) << error_str;
52 return NULL;
[email protected]1d697f32011-11-28 11:57:5153 }
[email protected]26193462012-01-05 10:36:5554 base::DictionaryValue* dict = NULL;
55 if (!value->GetAsDictionary(&dict))
56 return NULL;
57 base::ListValue* list = NULL;
58 if (!dict->GetList("plugins", &list))
59 return NULL;
60 return list->DeepCopy();
61#else
62 return new base::ListValue();
[email protected]1d697f32011-11-28 11:57:5163#endif
[email protected]1d697f32011-11-28 11:57:5164}
65
66PluginFinder::~PluginFinder() {
[email protected]f99c87d2011-12-02 02:28:1267 STLDeleteValues(&installers_);
[email protected]1d697f32011-11-28 11:57:5168}
69
70void PluginFinder::FindPlugin(
71 const std::string& mime_type,
72 const std::string& language,
[email protected]27c483892012-02-09 15:59:1073 const FindPluginCallback& callback) {
74 PluginInstaller* installer = FindPluginInternal(mime_type, language);
75 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, installer));
76}
77
78void PluginFinder::FindPluginWithIdentifier(
79 const std::string& identifier,
80 const FindPluginCallback& found_callback) {
81 PluginInstaller* installer = NULL;
82 std::map<std::string, PluginInstaller*>::const_iterator it =
83 installers_.find(identifier);
84 if (it != installers_.end()) {
85 installer = it->second;
86 } else {
87 for (ListValue::const_iterator plugin_it = plugin_list_->begin();
88 plugin_it != plugin_list_->end(); ++plugin_it) {
89 const base::DictionaryValue* plugin = NULL;
90 if (!(*plugin_it)->GetAsDictionary(&plugin)) {
91 NOTREACHED();
92 continue;
93 }
94 std::string id;
95 bool success = plugin->GetString("identifier", &id);
[email protected]37be0492012-02-08 21:52:2896 DCHECK(success);
[email protected]27c483892012-02-09 15:59:1097 if (id == identifier) {
98 installer = CreateInstaller(identifier, plugin);
99 break;
[email protected]37be0492012-02-08 21:52:28100 }
101 }
102 }
[email protected]27c483892012-02-09 15:59:10103 MessageLoop::current()->PostTask(FROM_HERE,
104 base::Bind(found_callback, installer));
105}
106
107PluginInstaller* PluginFinder::CreateInstaller(
108 const std::string& identifier,
109 const base::DictionaryValue* plugin_dict) {
110 DCHECK(!installers_[identifier]);
111 std::string url;
112 bool success = plugin_dict->GetString("url", &url);
113 DCHECK(success);
114 std::string help_url;
115 plugin_dict->GetString("help_url", &help_url);
116 string16 name;
117 success = plugin_dict->GetString("name", &name);
118 DCHECK(success);
119 bool display_url = false;
120 plugin_dict->GetBoolean("displayurl", &display_url);
121 PluginInstaller*installer = new PluginInstaller(identifier,
122 GURL(url),
123 GURL(help_url),
124 name,
125 display_url);
126 installers_[identifier] = installer;
127 return installer;
128}
129
130PluginInstaller* PluginFinder::FindPluginInternal(
131 const std::string& mime_type,
132 const std::string& language) {
133 if (!g_browser_process->local_state()->GetBoolean(
134 prefs::kDisablePluginFinder)) {
135 for (ListValue::const_iterator plugin_it = plugin_list_->begin();
136 plugin_it != plugin_list_->end(); ++plugin_it) {
137 const base::DictionaryValue* plugin = NULL;
138 if (!(*plugin_it)->GetAsDictionary(&plugin)) {
139 NOTREACHED();
140 continue;
141 }
142 std::string language_str;
143 bool success = plugin->GetString("lang", &language_str);
144 DCHECK(success);
145 if (language_str != language)
146 continue;
147 ListValue* mime_types = NULL;
148 success = plugin->GetList("mime_types", &mime_types);
149 DCHECK(success);
150 for (ListValue::const_iterator mime_type_it = mime_types->begin();
151 mime_type_it != mime_types->end(); ++mime_type_it) {
152 std::string mime_type_str;
153 success = (*mime_type_it)->GetAsString(&mime_type_str);
154 DCHECK(success);
155 if (mime_type_str == mime_type) {
156 std::string identifier;
157 bool success = plugin->GetString("identifier", &identifier);
158 DCHECK(success);
159 std::map<std::string, PluginInstaller*>::const_iterator it =
160 installers_.find(identifier);
161 if (it != installers_.end())
162 return it->second;
163 return CreateInstaller(identifier, plugin);
164 }
165 }
166 }
167 }
168 return NULL;
[email protected]1d697f32011-11-28 11:57:51169}