OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "content/browser/plugin_service_impl.h" | 5 #include "content/browser/plugin_service_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
| 13 #include "base/metrics/histogram.h" |
13 #include "base/path_service.h" | 14 #include "base/path_service.h" |
14 #include "base/string_util.h" | 15 #include "base/string_util.h" |
15 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
16 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
17 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
18 #include "base/values.h" | 19 #include "base/values.h" |
19 #include "content/browser/ppapi_plugin_process_host.h" | 20 #include "content/browser/ppapi_plugin_process_host.h" |
20 #include "content/browser/renderer_host/render_process_host_impl.h" | 21 #include "content/browser/renderer_host/render_process_host_impl.h" |
21 #include "content/browser/renderer_host/render_view_host_impl.h" | 22 #include "content/browser/renderer_host/render_view_host_impl.h" |
22 #include "content/common/pepper_plugin_registry.h" | 23 #include "content/common/pepper_plugin_registry.h" |
23 #include "content/common/plugin_messages.h" | 24 #include "content/common/plugin_messages.h" |
24 #include "content/common/utility_messages.h" | 25 #include "content/common/utility_messages.h" |
25 #include "content/common/view_messages.h" | 26 #include "content/common/view_messages.h" |
26 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
27 #include "content/public/browser/content_browser_client.h" | 28 #include "content/public/browser/content_browser_client.h" |
28 #include "content/public/browser/plugin_service_filter.h" | 29 #include "content/public/browser/plugin_service_filter.h" |
29 #include "content/public/browser/resource_context.h" | 30 #include "content/public/browser/resource_context.h" |
30 #include "content/public/common/content_switches.h" | 31 #include "content/public/common/content_switches.h" |
31 #include "content/public/common/process_type.h" | 32 #include "content/public/common/process_type.h" |
32 #include "webkit/plugins/npapi/plugin_list.h" | 33 #include "webkit/plugins/npapi/plugin_list.h" |
33 #include "webkit/plugins/npapi/plugin_utils.h" | 34 #include "webkit/plugins/npapi/plugin_utils.h" |
| 35 #include "webkit/plugins/plugin_constants.h" |
34 #include "webkit/plugins/webplugininfo.h" | 36 #include "webkit/plugins/webplugininfo.h" |
35 | 37 |
36 #if defined(OS_WIN) | 38 #if defined(OS_WIN) |
37 #include "webkit/plugins/npapi/plugin_constants_win.h" | 39 #include "webkit/plugins/npapi/plugin_constants_win.h" |
38 #endif | 40 #endif |
39 | 41 |
40 #if defined(OS_POSIX) | 42 #if defined(OS_POSIX) |
41 #include "content/browser/plugin_loader_posix.h" | 43 #include "content/browser/plugin_loader_posix.h" |
42 #endif | 44 #endif |
43 | 45 |
44 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) | 46 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
45 using ::base::FilePathWatcher; | 47 using ::base::FilePathWatcher; |
46 #endif | 48 #endif |
47 | 49 |
48 namespace content { | 50 namespace content { |
49 namespace { | 51 namespace { |
50 | 52 |
| 53 // This enum is used to collect Flash usage data. |
| 54 enum FlashUsage { |
| 55 // Number of browser processes that have started at least one NPAPI Flash |
| 56 // process during their lifetime. |
| 57 START_NPAPI_FLASH_AT_LEAST_ONCE, |
| 58 // Number of browser processes that have started at least one PPAPI Flash |
| 59 // process during their lifetime. |
| 60 START_PPAPI_FLASH_AT_LEAST_ONCE, |
| 61 // Total number of browser processes. |
| 62 TOTAL_BROWSER_PROCESSES, |
| 63 FLASH_USAGE_ENUM_COUNT |
| 64 }; |
| 65 |
51 bool LoadPluginListInProcess() { | 66 bool LoadPluginListInProcess() { |
52 #if defined(OS_WIN) | 67 #if defined(OS_WIN) |
53 return true; | 68 return true; |
54 #else | 69 #else |
55 // If on POSIX, we don't want to load the list of NPAPI plugins in-process as | 70 // If on POSIX, we don't want to load the list of NPAPI plugins in-process as |
56 // that causes instability. | 71 // that causes instability. |
57 return !webkit::npapi::NPAPIPluginsSupported(); | 72 return !webkit::npapi::NPAPIPluginsSupported(); |
58 #endif | 73 #endif |
59 } | 74 } |
60 | 75 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 } | 129 } |
115 } | 130 } |
116 | 131 |
117 // static | 132 // static |
118 PluginServiceImpl* PluginServiceImpl::GetInstance() { | 133 PluginServiceImpl* PluginServiceImpl::GetInstance() { |
119 return Singleton<PluginServiceImpl>::get(); | 134 return Singleton<PluginServiceImpl>::get(); |
120 } | 135 } |
121 | 136 |
122 PluginServiceImpl::PluginServiceImpl() | 137 PluginServiceImpl::PluginServiceImpl() |
123 : plugin_list_(NULL), filter_(NULL) { | 138 : plugin_list_(NULL), filter_(NULL) { |
| 139 // Collect the total number of browser processes (which create |
| 140 // PluginServiceImpl objects, to be precise). The number is used to normalize |
| 141 // the number of processes which start at least one NPAPI/PPAPI Flash process. |
| 142 static bool counted = false; |
| 143 if (!counted) { |
| 144 counted = true; |
| 145 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashUsage", TOTAL_BROWSER_PROCESSES, |
| 146 FLASH_USAGE_ENUM_COUNT); |
| 147 } |
124 } | 148 } |
125 | 149 |
126 PluginServiceImpl::~PluginServiceImpl() { | 150 PluginServiceImpl::~PluginServiceImpl() { |
127 #if defined(OS_WIN) | 151 #if defined(OS_WIN) |
128 // Release the events since they're owned by RegKey, not WaitableEvent. | 152 // Release the events since they're owned by RegKey, not WaitableEvent. |
129 hkcu_watcher_.StopWatching(); | 153 hkcu_watcher_.StopWatching(); |
130 hklm_watcher_.StopWatching(); | 154 hklm_watcher_.StopWatching(); |
131 if (hkcu_event_.get()) | 155 if (hkcu_event_.get()) |
132 hkcu_event_->Release(); | 156 hkcu_event_->Release(); |
133 if (hklm_event_.get()) | 157 if (hklm_event_.get()) |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 299 |
276 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); | 300 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); |
277 if (plugin_host) | 301 if (plugin_host) |
278 return plugin_host; | 302 return plugin_host; |
279 | 303 |
280 webkit::WebPluginInfo info; | 304 webkit::WebPluginInfo info; |
281 if (!GetPluginInfoByPath(plugin_path, &info)) { | 305 if (!GetPluginInfoByPath(plugin_path, &info)) { |
282 return NULL; | 306 return NULL; |
283 } | 307 } |
284 | 308 |
| 309 // Record when NPAPI Flash process is started for the first time. |
| 310 static bool counted = false; |
| 311 if (!counted && UTF16ToUTF8(info.name) == kFlashPluginName) { |
| 312 counted = true; |
| 313 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashUsage", |
| 314 START_NPAPI_FLASH_AT_LEAST_ONCE, |
| 315 FLASH_USAGE_ENUM_COUNT); |
| 316 } |
| 317 |
285 // This plugin isn't loaded by any plugin process, so create a new process. | 318 // This plugin isn't loaded by any plugin process, so create a new process. |
286 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); | 319 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); |
287 if (!new_host->Init(info)) { | 320 if (!new_host->Init(info)) { |
288 NOTREACHED(); // Init is not expected to fail. | 321 NOTREACHED(); // Init is not expected to fail. |
289 return NULL; | 322 return NULL; |
290 } | 323 } |
291 return new_host.release(); | 324 return new_host.release(); |
292 } | 325 } |
293 | 326 |
294 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( | 327 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( |
295 int render_process_id, | 328 int render_process_id, |
296 const base::FilePath& plugin_path, | 329 const base::FilePath& plugin_path, |
297 const base::FilePath& profile_data_directory, | 330 const base::FilePath& profile_data_directory, |
298 PpapiPluginProcessHost::PluginClient* client) { | 331 PpapiPluginProcessHost::PluginClient* client) { |
299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
300 | 333 |
301 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) | 334 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) |
302 return NULL; | 335 return NULL; |
303 | 336 |
304 PpapiPluginProcessHost* plugin_host = | 337 PpapiPluginProcessHost* plugin_host = |
305 FindPpapiPluginProcess(plugin_path, profile_data_directory); | 338 FindPpapiPluginProcess(plugin_path, profile_data_directory); |
306 if (plugin_host) | 339 if (plugin_host) |
307 return plugin_host; | 340 return plugin_host; |
308 | 341 |
309 // Validate that the plugin is actually registered. | 342 // Validate that the plugin is actually registered. |
310 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); | 343 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); |
311 if (!info) | 344 if (!info) |
312 return NULL; | 345 return NULL; |
313 | 346 |
| 347 // Record when PPAPI Flash process is started for the first time. |
| 348 static bool counted = false; |
| 349 if (!counted && info->name == kFlashPluginName) { |
| 350 counted = true; |
| 351 UMA_HISTOGRAM_ENUMERATION("Plugin.FlashUsage", |
| 352 START_PPAPI_FLASH_AT_LEAST_ONCE, |
| 353 FLASH_USAGE_ENUM_COUNT); |
| 354 } |
| 355 |
314 // This plugin isn't loaded by any plugin process, so create a new process. | 356 // This plugin isn't loaded by any plugin process, so create a new process. |
315 return PpapiPluginProcessHost::CreatePluginHost( | 357 return PpapiPluginProcessHost::CreatePluginHost( |
316 *info, profile_data_directory, | 358 *info, profile_data_directory, |
317 client->GetResourceContext()->GetHostResolver()); | 359 client->GetResourceContext()->GetHostResolver()); |
318 } | 360 } |
319 | 361 |
320 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( | 362 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( |
321 int render_process_id, | 363 int render_process_id, |
322 const base::FilePath& plugin_path) { | 364 const base::FilePath& plugin_path) { |
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 void PluginServiceImpl::GetInternalPlugins( | 790 void PluginServiceImpl::GetInternalPlugins( |
749 std::vector<webkit::WebPluginInfo>* plugins) { | 791 std::vector<webkit::WebPluginInfo>* plugins) { |
750 plugin_list_->GetInternalPlugins(plugins); | 792 plugin_list_->GetInternalPlugins(plugins); |
751 } | 793 } |
752 | 794 |
753 webkit::npapi::PluginList* PluginServiceImpl::GetPluginList() { | 795 webkit::npapi::PluginList* PluginServiceImpl::GetPluginList() { |
754 return plugin_list_; | 796 return plugin_list_; |
755 } | 797 } |
756 | 798 |
757 } // namespace content | 799 } // namespace content |
OLD | NEW |