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

Side by Side Diff: chrome/common/chrome_plugin_lib.cc

Issue 6576020: Remove Gears from Chrome (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: windows fixes Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « chrome/common/chrome_plugin_lib.h ('k') | chrome/common/chrome_plugin_util.h » ('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) 2011 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/common/chrome_plugin_lib.h"
6
7 #include "base/command_line.h"
8 #include "base/hash_tables.h"
9 #include "base/message_loop.h"
10 #include "base/metrics/histogram.h"
11 #include "base/path_service.h"
12 #include "base/perftimer.h"
13 #include "base/string_util.h"
14 #include "base/threading/platform_thread.h"
15 #include "base/threading/thread.h"
16 #include "chrome/common/chrome_counters.h"
17 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "content/common/notification_service.h"
20 #include "webkit/plugins/npapi/plugin_list.h"
21
22 #if defined(OS_WIN)
23 #include "base/win/registry.h"
24 #endif
25
26 using base::TimeDelta;
27
28 // TODO(port): revisit when plugins happier
29 #if defined(OS_WIN)
30 const wchar_t ChromePluginLib::kRegistryChromePlugins[] =
31 L"Software\\Google\\Chrome\\Plugins";
32 static const wchar_t kRegistryLoadOnStartup[] = L"LoadOnStartup";
33 static const wchar_t kRegistryPath[] = L"Path";
34 #endif
35
36 typedef base::hash_map<FilePath, scoped_refptr<ChromePluginLib> >
37 PluginMap;
38
39 // A map of all the instantiated plugins.
40 static PluginMap* g_loaded_libs;
41
42 // The thread plugins are loaded and used in, lazily initialized upon
43 // the first creation call.
44 static base::PlatformThreadId g_plugin_thread_id = 0;
45 static MessageLoop* g_plugin_thread_loop = NULL;
46
47 static bool IsSingleProcessMode() {
48 // We don't support ChromePlugins in single-process mode.
49 return CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess);
50 }
51
52 // static
53 bool ChromePluginLib::IsInitialized() {
54 return (g_loaded_libs != NULL);
55 }
56
57 // static
58 ChromePluginLib* ChromePluginLib::Create(const FilePath& filename,
59 const CPBrowserFuncs* bfuncs) {
60 // Keep a map of loaded plugins to ensure we only load each library once.
61 if (!g_loaded_libs) {
62 g_loaded_libs = new PluginMap();
63 g_plugin_thread_id = base::PlatformThread::CurrentId();
64 g_plugin_thread_loop = MessageLoop::current();
65 }
66 DCHECK(IsPluginThread());
67
68 PluginMap::const_iterator iter = g_loaded_libs->find(filename);
69 if (iter != g_loaded_libs->end())
70 return iter->second;
71
72 scoped_refptr<ChromePluginLib> plugin(new ChromePluginLib(filename));
73 if (!plugin->CP_Initialize(bfuncs))
74 return NULL;
75
76 (*g_loaded_libs)[filename] = plugin;
77 return plugin;
78 }
79
80 // static
81 ChromePluginLib* ChromePluginLib::Find(const FilePath& filename) {
82 if (g_loaded_libs) {
83 PluginMap::const_iterator iter = g_loaded_libs->find(filename);
84 if (iter != g_loaded_libs->end())
85 return iter->second;
86 }
87 return NULL;
88 }
89
90 // static
91 void ChromePluginLib::Destroy(const FilePath& filename) {
92 DCHECK(g_loaded_libs);
93 PluginMap::iterator iter = g_loaded_libs->find(filename);
94 if (iter != g_loaded_libs->end()) {
95 iter->second->Unload();
96 g_loaded_libs->erase(iter);
97 }
98 }
99
100 // static
101 bool ChromePluginLib::IsPluginThread() {
102 return base::PlatformThread::CurrentId() == g_plugin_thread_id;
103 }
104
105 // static
106 MessageLoop* ChromePluginLib::GetPluginThreadLoop() {
107 return g_plugin_thread_loop;
108 }
109
110 // static
111 void ChromePluginLib::RegisterPluginsWithNPAPI() {
112 // We don't support ChromePlugins in single-process mode.
113 if (IsSingleProcessMode())
114 return;
115
116 FilePath path;
117 // Register Gears, if available.
118 if (PathService::Get(chrome::FILE_GEARS_PLUGIN, &path))
119 webkit::npapi::PluginList::Singleton()->AddExtraPluginPath(path);
120 }
121
122 static void LogPluginLoadTime(const TimeDelta &time) {
123 UMA_HISTOGRAM_TIMES("Gears.LoadTime", time);
124 }
125
126 // static
127 void ChromePluginLib::LoadChromePlugins(const CPBrowserFuncs* bfuncs) {
128 static bool loaded = false;
129 if (loaded)
130 return;
131 loaded = true;
132
133 // We don't support ChromePlugins in single-process mode.
134 if (IsSingleProcessMode())
135 return;
136
137 FilePath path;
138 if (!PathService::Get(chrome::FILE_GEARS_PLUGIN, &path))
139 return;
140
141 PerfTimer timer;
142 ChromePluginLib::Create(path, bfuncs);
143 LogPluginLoadTime(timer.Elapsed());
144
145 // TODO(mpcomplete): disabled loading of plugins from the registry until we
146 // phase out registry keys from the gears installer.
147 #if 0
148 for (RegistryKeyIterator iter(HKEY_CURRENT_USER, kRegistryChromePlugins);
149 iter.Valid(); ++iter) {
150 // Use the registry to gather plugin across the file system.
151 std::wstring reg_path = kRegistryChromePlugins;
152 reg_path.append(L"\\");
153 reg_path.append(iter.Name());
154 base::win::RegKey key(HKEY_CURRENT_USER, reg_path.c_str());
155
156 DWORD is_persistent = 0;
157 key.ReadValueDW(kRegistryLoadOnStartup, &is_persistent);
158 if (is_persistent) {
159 std::wstring path;
160 if (key.ReadValue(kRegistryPath, &path) == ERROR_SUCCESS) {
161 ChromePluginLib::Create(path, bfuncs);
162 }
163 }
164 }
165 #endif
166 }
167
168 // static
169 void ChromePluginLib::UnloadAllPlugins() {
170 if (g_loaded_libs) {
171 PluginMap::iterator it;
172 for (PluginMap::iterator it = g_loaded_libs->begin();
173 it != g_loaded_libs->end(); ++it) {
174 it->second->Unload();
175 }
176 delete g_loaded_libs;
177 g_loaded_libs = NULL;
178 }
179 }
180
181 const CPPluginFuncs& ChromePluginLib::functions() const {
182 DCHECK(initialized_);
183 DCHECK(IsPluginThread());
184 return plugin_funcs_;
185 }
186
187 ChromePluginLib::ChromePluginLib(const FilePath& filename)
188 : filename_(filename),
189 #if defined(OS_WIN)
190 module_(0),
191 #endif
192 initialized_(false),
193 CP_VersionNegotiate_(NULL),
194 CP_Initialize_(NULL),
195 CP_Test_(NULL) {
196 memset((void*)&plugin_funcs_, 0, sizeof(plugin_funcs_));
197 }
198
199 ChromePluginLib::~ChromePluginLib() {
200 }
201
202 bool ChromePluginLib::CP_Initialize(const CPBrowserFuncs* bfuncs) {
203 VLOG(1) << "ChromePluginLib::CP_Initialize(" << filename_.value()
204 << "): initialized=" << initialized_;
205 if (initialized_)
206 return true;
207
208 if (!Load())
209 return false;
210
211 if (CP_VersionNegotiate_) {
212 uint16 selected_version = 0;
213 CPError rv = CP_VersionNegotiate_(CP_VERSION, CP_VERSION,
214 &selected_version);
215 if ((rv != CPERR_SUCCESS) || (selected_version != CP_VERSION))
216 return false;
217 }
218
219 plugin_funcs_.size = sizeof(plugin_funcs_);
220 CPError rv = CP_Initialize_(cpid(), bfuncs, &plugin_funcs_);
221 initialized_ = (rv == CPERR_SUCCESS) &&
222 (CP_GET_MAJOR_VERSION(plugin_funcs_.version) == CP_MAJOR_VERSION) &&
223 (CP_GET_MINOR_VERSION(plugin_funcs_.version) <= CP_MINOR_VERSION);
224 VLOG(1) << "ChromePluginLib::CP_Initialize(" << filename_.value()
225 << "): initialized=" << initialized_ << "): result=" << rv;
226
227 return initialized_;
228 }
229
230 void ChromePluginLib::CP_Shutdown() {
231 DCHECK(initialized_);
232 functions().shutdown();
233 initialized_ = false;
234 memset((void*)&plugin_funcs_, 0, sizeof(plugin_funcs_));
235 }
236
237 int ChromePluginLib::CP_Test(void* param) {
238 DCHECK(initialized_);
239 if (!CP_Test_)
240 return -1;
241 return CP_Test_(param);
242 }
243
244 bool ChromePluginLib::Load() {
245 #if !defined(OS_WIN)
246 // Mac and Linux won't implement Gears.
247 return false;
248 #else
249 DCHECK(module_ == 0);
250
251 module_ = LoadLibrary(filename_.value().c_str());
252 if (module_ == 0)
253 return false;
254
255 // required initialization function
256 CP_Initialize_ = reinterpret_cast<CP_InitializeFunc>
257 (GetProcAddress(module_, "CP_Initialize"));
258
259 if (!CP_Initialize_) {
260 FreeLibrary(module_);
261 module_ = 0;
262 return false;
263 }
264
265 // optional version negotiation function
266 CP_VersionNegotiate_ = reinterpret_cast<CP_VersionNegotiateFunc>
267 (GetProcAddress(module_, "CP_VersionNegotiate"));
268
269 // optional test function
270 CP_Test_ = reinterpret_cast<CP_TestFunc>
271 (GetProcAddress(module_, "CP_Test"));
272
273 return true;
274 #endif
275 }
276
277 void ChromePluginLib::Unload() {
278 NotificationService::current()->Notify(
279 NotificationType::CHROME_PLUGIN_UNLOADED,
280 Source<ChromePluginLib>(this),
281 NotificationService::NoDetails());
282
283 if (initialized_)
284 CP_Shutdown();
285
286 #if defined(OS_WIN)
287 if (module_) {
288 FreeLibrary(module_);
289 module_ = 0;
290 }
291 #endif
292 }
OLDNEW
« no previous file with comments | « chrome/common/chrome_plugin_lib.h ('k') | chrome/common/chrome_plugin_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698