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). 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 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 171 void ChromeContentClient::SetActiveURL(const GURL& url) { 172 child_process_logging::SetActiveURL(url); 173 } 174 175 void ChromeContentClient::SetGpuInfo(const GPUInfo& gpu_info) { 176 child_process_logging::SetGpuInfo(gpu_info); 177 } 178 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