atom_content_client.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // Copyright (c) 2014 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/app/atom_content_client.h"
  5. #include <string>
  6. #include <vector>
  7. #include "atom/common/atom_version.h"
  8. #include "atom/common/chrome_version.h"
  9. #include "atom/common/options_switches.h"
  10. #include "base/command_line.h"
  11. #include "base/files/file_util.h"
  12. #include "base/strings/string_split.h"
  13. #include "base/strings/string_util.h"
  14. #include "base/strings/utf_string_conversions.h"
  15. #include "content/public/common/content_constants.h"
  16. #include "content/public/common/pepper_plugin_info.h"
  17. #include "content/public/common/user_agent.h"
  18. #include "media/media_features.h"
  19. #include "ppapi/shared_impl/ppapi_permissions.h"
  20. #include "third_party/widevine/cdm/widevine_cdm_common.h"
  21. #include "ui/base/l10n/l10n_util.h"
  22. #include "url/url_constants.h"
  23. #if defined(WIDEVINE_CDM_AVAILABLE)
  24. #include "base/native_library.h"
  25. #include "base/strings/stringprintf.h"
  26. #include "chrome/common/widevine_cdm_constants.h"
  27. #include "content/public/common/cdm_info.h"
  28. #include "media/base/video_codecs.h"
  29. #endif // defined(WIDEVINE_CDM_AVAILABLE)
  30. #if defined(ENABLE_PDF_VIEWER)
  31. #include "atom/common/atom_constants.h"
  32. #include "pdf/pdf.h"
  33. #endif // defined(ENABLE_PDF_VIEWER)
  34. namespace atom {
  35. namespace {
  36. #if defined(WIDEVINE_CDM_AVAILABLE)
  37. bool IsWidevineAvailable(base::FilePath* adapter_path,
  38. base::FilePath* cdm_path,
  39. std::vector<media::VideoCodec>* codecs_supported) {
  40. static enum {
  41. NOT_CHECKED,
  42. FOUND,
  43. NOT_FOUND,
  44. } widevine_cdm_file_check = NOT_CHECKED;
  45. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  46. *adapter_path = command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
  47. if (!adapter_path->empty()) {
  48. *cdm_path = adapter_path->DirName().AppendASCII(
  49. base::GetNativeLibraryName(kWidevineCdmLibraryName));
  50. if (widevine_cdm_file_check == NOT_CHECKED) {
  51. widevine_cdm_file_check =
  52. (base::PathExists(*adapter_path) && base::PathExists(*cdm_path))
  53. ? FOUND
  54. : NOT_FOUND;
  55. }
  56. if (widevine_cdm_file_check == FOUND) {
  57. // Add the supported codecs as if they came from the component manifest.
  58. // This list must match the CDM that is being bundled with Chrome.
  59. codecs_supported->push_back(media::VideoCodec::kCodecVP8);
  60. codecs_supported->push_back(media::VideoCodec::kCodecVP9);
  61. #if BUILDFLAG(USE_PROPRIETARY_CODECS)
  62. codecs_supported->push_back(media::VideoCodec::kCodecH264);
  63. #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
  64. return true;
  65. }
  66. }
  67. return false;
  68. }
  69. void AddWidevineAdapterFromCommandLine(
  70. base::CommandLine* command_line,
  71. std::vector<content::PepperPluginInfo>* plugins) {
  72. base::FilePath adapter_path;
  73. base::FilePath cdm_path;
  74. std::vector<media::VideoCodec> video_codecs_supported;
  75. if (IsWidevineAvailable(&adapter_path, &cdm_path, &video_codecs_supported)) {
  76. auto cdm_version_string =
  77. command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
  78. content::PepperPluginInfo info;
  79. info.is_out_of_process = true;
  80. info.path = adapter_path;
  81. info.name = kWidevineCdmDisplayName;
  82. info.description =
  83. base::StringPrintf("%s (version: %s)", kWidevineCdmDescription,
  84. cdm_version_string.c_str());
  85. info.version = cdm_version_string;
  86. info.permissions = kWidevineCdmPluginPermissions;
  87. content::WebPluginMimeType mime_type(kWidevineCdmPluginMimeType,
  88. kWidevineCdmPluginExtension,
  89. kWidevineCdmPluginMimeTypeDescription);
  90. info.mime_types.push_back(mime_type);
  91. plugins->push_back(info);
  92. }
  93. }
  94. #endif // defined(WIDEVINE_CDM_AVAILABLE)
  95. #if defined(ENABLE_PEPPER_FLASH)
  96. content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
  97. const std::string& version) {
  98. content::PepperPluginInfo plugin;
  99. plugin.is_out_of_process = true;
  100. plugin.name = content::kFlashPluginName;
  101. plugin.path = path;
  102. plugin.permissions = ppapi::PERMISSION_ALL_BITS;
  103. std::vector<std::string> flash_version_numbers = base::SplitString(
  104. version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  105. if (flash_version_numbers.empty())
  106. flash_version_numbers.push_back("11");
  107. // |SplitString()| puts in an empty string given an empty string. :(
  108. else if (flash_version_numbers[0].empty())
  109. flash_version_numbers[0] = "11";
  110. if (flash_version_numbers.size() < 2)
  111. flash_version_numbers.push_back("2");
  112. if (flash_version_numbers.size() < 3)
  113. flash_version_numbers.push_back("999");
  114. if (flash_version_numbers.size() < 4)
  115. flash_version_numbers.push_back("999");
  116. // E.g., "Shockwave Flash 10.2 r154":
  117. plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
  118. flash_version_numbers[1] + " r" +
  119. flash_version_numbers[2];
  120. plugin.version = base::JoinString(flash_version_numbers, ".");
  121. content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
  122. content::kFlashPluginSwfExtension,
  123. content::kFlashPluginSwfDescription);
  124. plugin.mime_types.push_back(swf_mime_type);
  125. content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
  126. content::kFlashPluginSplExtension,
  127. content::kFlashPluginSplDescription);
  128. plugin.mime_types.push_back(spl_mime_type);
  129. return plugin;
  130. }
  131. void AddPepperFlashFromCommandLine(
  132. base::CommandLine* command_line,
  133. std::vector<content::PepperPluginInfo>* plugins) {
  134. base::FilePath flash_path =
  135. command_line->GetSwitchValuePath(switches::kPpapiFlashPath);
  136. if (flash_path.empty())
  137. return;
  138. auto flash_version =
  139. command_line->GetSwitchValueASCII(switches::kPpapiFlashVersion);
  140. plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
  141. }
  142. #endif // defined(ENABLE_PEPPER_FLASH)
  143. void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
  144. #if defined(ENABLE_PDF_VIEWER)
  145. content::PepperPluginInfo pdf_info;
  146. pdf_info.is_internal = true;
  147. pdf_info.is_out_of_process = true;
  148. pdf_info.name = "Chromium PDF Viewer";
  149. pdf_info.description = "Portable Document Format";
  150. pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
  151. content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
  152. "Portable Document Format");
  153. pdf_info.mime_types.push_back(pdf_mime_type);
  154. pdf_info.internal_entry_points.get_interface = chrome_pdf::PPP_GetInterface;
  155. pdf_info.internal_entry_points.initialize_module =
  156. chrome_pdf::PPP_InitializeModule;
  157. pdf_info.internal_entry_points.shutdown_module =
  158. chrome_pdf::PPP_ShutdownModule;
  159. pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
  160. plugins->push_back(pdf_info);
  161. #endif // defined(ENABLE_PDF_VIEWER)
  162. }
  163. void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
  164. const char* separator,
  165. const char* cmd_switch) {
  166. auto* command_line = base::CommandLine::ForCurrentProcess();
  167. auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
  168. if (!string_with_separator.empty())
  169. *vec = base::SplitString(string_with_separator, separator,
  170. base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  171. }
  172. } // namespace
  173. AtomContentClient::AtomContentClient() {}
  174. AtomContentClient::~AtomContentClient() {}
  175. std::string AtomContentClient::GetProduct() const {
  176. return "Chrome/" CHROME_VERSION_STRING;
  177. }
  178. std::string AtomContentClient::GetUserAgent() const {
  179. return content::BuildUserAgentFromProduct("Chrome/" CHROME_VERSION_STRING
  180. " " ATOM_PRODUCT_NAME
  181. "/" ATOM_VERSION_STRING);
  182. }
  183. base::string16 AtomContentClient::GetLocalizedString(int message_id) const {
  184. return l10n_util::GetStringUTF16(message_id);
  185. }
  186. void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
  187. schemes->standard_schemes.push_back("chrome-extension");
  188. std::vector<std::string> splited;
  189. ConvertStringWithSeparatorToVector(&splited, ",",
  190. switches::kRegisterServiceWorkerSchemes);
  191. for (const std::string& scheme : splited)
  192. schemes->service_worker_schemes.push_back(scheme);
  193. schemes->service_worker_schemes.push_back(url::kFileScheme);
  194. ConvertStringWithSeparatorToVector(&splited, ",", switches::kSecureSchemes);
  195. for (const std::string& scheme : splited)
  196. schemes->secure_schemes.push_back(scheme);
  197. }
  198. void AtomContentClient::AddPepperPlugins(
  199. std::vector<content::PepperPluginInfo>* plugins) {
  200. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  201. #if defined(ENABLE_PEPPER_FLASH)
  202. AddPepperFlashFromCommandLine(command_line, plugins);
  203. #endif // defined(ENABLE_PEPPER_FLASH)
  204. #if defined(WIDEVINE_CDM_AVAILABLE)
  205. AddWidevineAdapterFromCommandLine(command_line, plugins);
  206. #endif // defined(WIDEVINE_CDM_AVAILABLE)
  207. ComputeBuiltInPlugins(plugins);
  208. }
  209. void AtomContentClient::AddContentDecryptionModules(
  210. std::vector<content::CdmInfo>* cdms,
  211. std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
  212. if (cdms) {
  213. #if defined(WIDEVINE_CDM_AVAILABLE)
  214. base::FilePath adapter_path;
  215. base::FilePath cdm_path;
  216. std::vector<media::VideoCodec> video_codecs_supported;
  217. bool supports_persistent_license = false;
  218. if (IsWidevineAvailable(&adapter_path, &cdm_path,
  219. &video_codecs_supported)) {
  220. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  221. auto cdm_version_string =
  222. command_line->GetSwitchValueASCII(switches::kWidevineCdmVersion);
  223. // CdmInfo needs |path| to be the actual Widevine library,
  224. // not the adapter, so adjust as necessary. It will be in the
  225. // same directory as the installed adapter.
  226. const base::Version version(cdm_version_string);
  227. DCHECK(version.IsValid());
  228. cdms->push_back(content::CdmInfo(
  229. kWidevineCdmDisplayName, kWidevineCdmGuid, version, cdm_path,
  230. kWidevineCdmFileSystemId, video_codecs_supported,
  231. supports_persistent_license, kWidevineKeySystem, false));
  232. }
  233. #endif // defined(WIDEVINE_CDM_AVAILABLE)
  234. }
  235. }
  236. } // namespace atom