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_content_client.h"
6
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/path_service.h"
10 #include "base/string_split.h"
11 #include "base/string_util.h"
12 #include "chrome/common/child_process_logging.h"
13 #include "chrome/common/chrome_paths.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "content/common/pepper_plugin_registry.h"
16 #include "remoting/client/plugin/pepper_entrypoints.h"
17
18 namespace {
19
20 const char* kPDFPluginName = "Chrome PDF Viewer";
21 const char* kPDFPluginMimeType = "application/pdf";
22 const char* kPDFPluginExtension = "pdf";
23 const char* kPDFPluginDescription = "Portable Document Format";
24
25 const char* kNaClPluginName = "Chrome NaCl";
26 const char* kNaClPluginMimeType = "application/x-nacl";
27 const char* kNaClPluginExtension = "nexe";
28 const char* kNaClPluginDescription = "Native Client Executable";
29
30 #if defined(ENABLE_REMOTING)
31 const char* kRemotingPluginMimeType = "pepper-application/x-chromoting";
32 #endif
33
34 const char* kFlashPluginName = "Shockwave Flash";
35 const char* kFlashPluginSwfMimeType = "application/x-shockwave-flash";
36 const char* kFlashPluginSwfExtension = "swf";
37 const char* kFlashPluginSwfDescription = "Shockwave Flash";
38 const char* kFlashPluginSplMimeType = "application/futuresplash";
39 const char* kFlashPluginSplExtension = "spl";
40 const char* kFlashPluginSplDescription = "FutureSplash Player";
41
42 #if !defined(NACL_WIN64) // The code this needs isn't linked on Win64 builds.
43
44 // Appends the known built-in plugins to the given vector. Some built-in
45 // plugins are "internal" which means they are compiled into the Chrome binary,
46 // and some are extra shared libraries distributed with the browser (these are
47 // not marked internal, aside from being automatically registered, they're just
48 // regular plugins).
ComputeBuiltInPlugins(std::vector<PepperPluginInfo> * plugins)49 void ComputeBuiltInPlugins(std::vector<PepperPluginInfo>* plugins) {
50 // PDF.
51 //
52 // Once we're sandboxed, we can't know if the PDF plugin is available or not;
53 // but (on Linux) this function is always called once before we're sandboxed.
54 // So the first time through test if the file is available and then skip the
55 // check on subsequent calls if yes.
56 static bool skip_pdf_file_check = false;
57 FilePath path;
58 if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path)) {
59 if (skip_pdf_file_check || file_util::PathExists(path)) {
60 PepperPluginInfo pdf;
61 pdf.path = path;
62 pdf.name = kPDFPluginName;
63 webkit::npapi::WebPluginMimeType pdf_mime_type(kPDFPluginMimeType,
64 kPDFPluginExtension,
65 kPDFPluginDescription);
66 pdf.mime_types.push_back(pdf_mime_type);
67 plugins->push_back(pdf);
68
69 skip_pdf_file_check = true;
70 }
71 }
72
73 // Handle the Native Client plugin just like the PDF plugin.
74 static bool skip_nacl_file_check = false;
75 if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) {
76 if (skip_nacl_file_check || file_util::PathExists(path)) {
77 PepperPluginInfo nacl;
78 nacl.path = path;
79 nacl.name = kNaClPluginName;
80 // Enable the Native Client Plugin based on the command line.
81 nacl.enabled = CommandLine::ForCurrentProcess()->HasSwitch(
82 switches::kEnableNaCl);
83 webkit::npapi::WebPluginMimeType nacl_mime_type(kNaClPluginMimeType,
84 kNaClPluginExtension,
85 kNaClPluginDescription);
86 nacl.mime_types.push_back(nacl_mime_type);
87 plugins->push_back(nacl);
88
89 skip_nacl_file_check = true;
90 }
91 }
92
93 // Remoting.
94 #if defined(ENABLE_REMOTING)
95 if (CommandLine::ForCurrentProcess()->HasSwitch(
96 switches::kEnableRemoting)) {
97 PepperPluginInfo info;
98 info.is_internal = true;
99 info.path = FilePath(FILE_PATH_LITERAL("internal-chromoting"));
100 webkit::npapi::WebPluginMimeType remoting_mime_type(kRemotingPluginMimeType,
101 std::string(),
102 std::string());
103 info.mime_types.push_back(remoting_mime_type);
104 info.internal_entry_points.get_interface = remoting::PPP_GetInterface;
105 info.internal_entry_points.initialize_module =
106 remoting::PPP_InitializeModule;
107 info.internal_entry_points.shutdown_module = remoting::PPP_ShutdownModule;
108
109 plugins->push_back(info);
110 }
111 #endif
112 }
113
AddOutOfProcessFlash(std::vector<PepperPluginInfo> * plugins)114 void AddOutOfProcessFlash(std::vector<PepperPluginInfo>* plugins) {
115 // Flash being out of process is handled separately than general plugins
116 // for testing purposes.
117 bool flash_out_of_process = !CommandLine::ForCurrentProcess()->HasSwitch(
118 switches::kPpapiFlashInProcess);
119
120 // Handle any Pepper Flash first.
121 const CommandLine::StringType flash_path =
122 CommandLine::ForCurrentProcess()->GetSwitchValueNative(
123 switches::kPpapiFlashPath);
124 if (flash_path.empty())
125 return;
126
127 PepperPluginInfo plugin;
128 plugin.is_out_of_process = flash_out_of_process;
129 plugin.path = FilePath(flash_path);
130 plugin.name = kFlashPluginName;
131
132 const std::string flash_version =
133 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
134 switches::kPpapiFlashVersion);
135 std::vector<std::string> flash_version_numbers;
136 base::SplitString(flash_version, '.', &flash_version_numbers);
137 if (flash_version_numbers.size() < 1)
138 flash_version_numbers.push_back("10");
139 // |SplitString()| puts in an empty string given an empty string. :(
140 else if (flash_version_numbers[0].empty())
141 flash_version_numbers[0] = "10";
142 if (flash_version_numbers.size() < 2)
143 flash_version_numbers.push_back("2");
144 if (flash_version_numbers.size() < 3)
145 flash_version_numbers.push_back("999");
146 if (flash_version_numbers.size() < 4)
147 flash_version_numbers.push_back("999");
148 // E.g., "Shockwave Flash 10.2 r154":
149 plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
150 flash_version_numbers[1] + " r" + flash_version_numbers[2];
151 plugin.version = JoinString(flash_version_numbers, '.');
152 webkit::npapi::WebPluginMimeType swf_mime_type(kFlashPluginSwfMimeType,
153 kFlashPluginSwfExtension,
154 kFlashPluginSwfDescription);
155 plugin.mime_types.push_back(swf_mime_type);
156 webkit::npapi::WebPluginMimeType spl_mime_type(kFlashPluginSplMimeType,
157 kFlashPluginSplExtension,
158 kFlashPluginSplDescription);
159 plugin.mime_types.push_back(spl_mime_type);
160 plugins->push_back(plugin);
161 }
162
163 #endif // !defined(NACL_WIN64)
164
165 } // namespace
166
167 namespace chrome {
168
169 const char* ChromeContentClient::kPDFPluginName = ::kPDFPluginName;
170
SetActiveURL(const GURL & url)171 void ChromeContentClient::SetActiveURL(const GURL& url) {
172 child_process_logging::SetActiveURL(url);
173 }
174
SetGpuInfo(const GPUInfo & gpu_info)175 void ChromeContentClient::SetGpuInfo(const GPUInfo& gpu_info) {
176 child_process_logging::SetGpuInfo(gpu_info);
177 }
178
AddPepperPlugins(std::vector<PepperPluginInfo> * plugins)179 void ChromeContentClient::AddPepperPlugins(
180 std::vector<PepperPluginInfo>* plugins) {
181 #if !defined(NACL_WIN64) // The code this needs isn't linked on Win64 builds.
182 ComputeBuiltInPlugins(plugins);
183 AddOutOfProcessFlash(plugins);
184 #endif
185 }
186
187 } // namespace chrome
188