atom_content_client.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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 "shell/app/atom_content_client.h"
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include "base/command_line.h"
  9. #include "base/files/file_util.h"
  10. #include "base/path_service.h"
  11. #include "base/strings/string_split.h"
  12. #include "base/strings/string_util.h"
  13. #include "base/strings/utf_string_conversions.h"
  14. #include "content/public/common/content_constants.h"
  15. #include "electron/buildflags/buildflags.h"
  16. #include "ppapi/buildflags/buildflags.h"
  17. #include "shell/browser/atom_paths.h"
  18. #include "shell/common/options_switches.h"
  19. #include "ui/base/l10n/l10n_util.h"
  20. #include "ui/base/resource/resource_bundle.h"
  21. #include "url/url_constants.h"
  22. // In SHARED_INTERMEDIATE_DIR.
  23. #include "widevine_cdm_version.h" // NOLINT(build/include_directory)
  24. #if defined(WIDEVINE_CDM_AVAILABLE)
  25. #include "base/native_library.h"
  26. #include "content/public/common/cdm_info.h"
  27. #include "media/base/video_codecs.h"
  28. #endif // defined(WIDEVINE_CDM_AVAILABLE)
  29. #if BUILDFLAG(ENABLE_PDF_VIEWER)
  30. #include "pdf/pdf.h"
  31. #include "shell/common/atom_constants.h"
  32. #endif // BUILDFLAG(ENABLE_PDF_VIEWER)
  33. #if BUILDFLAG(ENABLE_PLUGINS)
  34. #include "content/public/common/pepper_plugin_info.h"
  35. #include "ppapi/shared_impl/ppapi_permissions.h"
  36. #endif // BUILDFLAG(ENABLE_PLUGINS)
  37. namespace electron {
  38. namespace {
  39. #if defined(WIDEVINE_CDM_AVAILABLE)
  40. bool IsWidevineAvailable(
  41. base::FilePath* cdm_path,
  42. std::vector<media::VideoCodec>* codecs_supported,
  43. base::flat_set<media::CdmSessionType>* session_types_supported,
  44. base::flat_set<media::EncryptionMode>* modes_supported) {
  45. static enum {
  46. NOT_CHECKED,
  47. FOUND,
  48. NOT_FOUND,
  49. } widevine_cdm_file_check = NOT_CHECKED;
  50. if (widevine_cdm_file_check == NOT_CHECKED) {
  51. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  52. *cdm_path = command_line->GetSwitchValuePath(switches::kWidevineCdmPath);
  53. if (!cdm_path->empty()) {
  54. *cdm_path = cdm_path->AppendASCII(
  55. base::GetNativeLibraryName(kWidevineCdmLibraryName));
  56. widevine_cdm_file_check = base::PathExists(*cdm_path) ? FOUND : NOT_FOUND;
  57. }
  58. }
  59. if (widevine_cdm_file_check == FOUND) {
  60. // Add the supported codecs as if they came from the component manifest.
  61. // This list must match the CDM that is being bundled with Chrome.
  62. codecs_supported->push_back(media::VideoCodec::kCodecVP8);
  63. codecs_supported->push_back(media::VideoCodec::kCodecVP9);
  64. #if BUILDFLAG(USE_PROPRIETARY_CODECS)
  65. codecs_supported->push_back(media::VideoCodec::kCodecH264);
  66. #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
  67. // TODO(crbug.com/767941): Push persistent-license support info here once
  68. // we check in a new CDM that supports it on Linux.
  69. session_types_supported->insert(media::CdmSessionType::kTemporary);
  70. #if defined(OS_CHROMEOS)
  71. session_types_supported->insert(media::CdmSessionType::kPersistentLicense);
  72. #endif // defined(OS_CHROMEOS)
  73. modes_supported->insert(media::EncryptionMode::kCenc);
  74. return true;
  75. }
  76. return false;
  77. }
  78. #endif // defined(WIDEVINE_CDM_AVAILABLE)
  79. #if BUILDFLAG(ENABLE_PEPPER_FLASH)
  80. content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
  81. const std::string& version) {
  82. content::PepperPluginInfo plugin;
  83. plugin.is_out_of_process = true;
  84. plugin.name = content::kFlashPluginName;
  85. plugin.path = path;
  86. plugin.permissions = ppapi::PERMISSION_ALL_BITS;
  87. std::vector<std::string> flash_version_numbers = base::SplitString(
  88. version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  89. if (flash_version_numbers.empty())
  90. flash_version_numbers.push_back("11");
  91. // |SplitString()| puts in an empty string given an empty string. :(
  92. else if (flash_version_numbers[0].empty())
  93. flash_version_numbers[0] = "11";
  94. if (flash_version_numbers.size() < 2)
  95. flash_version_numbers.push_back("2");
  96. if (flash_version_numbers.size() < 3)
  97. flash_version_numbers.push_back("999");
  98. if (flash_version_numbers.size() < 4)
  99. flash_version_numbers.push_back("999");
  100. // E.g., "Shockwave Flash 10.2 r154":
  101. plugin.description = plugin.name + " " + flash_version_numbers[0] + "." +
  102. flash_version_numbers[1] + " r" +
  103. flash_version_numbers[2];
  104. plugin.version = base::JoinString(flash_version_numbers, ".");
  105. content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType,
  106. content::kFlashPluginSwfExtension,
  107. content::kFlashPluginSwfDescription);
  108. plugin.mime_types.push_back(swf_mime_type);
  109. content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType,
  110. content::kFlashPluginSplExtension,
  111. content::kFlashPluginSplDescription);
  112. plugin.mime_types.push_back(spl_mime_type);
  113. return plugin;
  114. }
  115. void AddPepperFlashFromCommandLine(
  116. base::CommandLine* command_line,
  117. std::vector<content::PepperPluginInfo>* plugins) {
  118. base::FilePath flash_path =
  119. command_line->GetSwitchValuePath(switches::kPpapiFlashPath);
  120. if (flash_path.empty())
  121. return;
  122. auto flash_version =
  123. command_line->GetSwitchValueASCII(switches::kPpapiFlashVersion);
  124. plugins->push_back(CreatePepperFlashInfo(flash_path, flash_version));
  125. }
  126. #endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
  127. #if BUILDFLAG(ENABLE_PLUGINS)
  128. void ComputeBuiltInPlugins(std::vector<content::PepperPluginInfo>* plugins) {
  129. #if BUILDFLAG(ENABLE_PDF_VIEWER)
  130. content::PepperPluginInfo pdf_info;
  131. pdf_info.is_internal = true;
  132. pdf_info.is_out_of_process = true;
  133. pdf_info.name = "Chromium PDF Viewer";
  134. pdf_info.description = "Portable Document Format";
  135. pdf_info.path = base::FilePath::FromUTF8Unsafe(kPdfPluginPath);
  136. content::WebPluginMimeType pdf_mime_type(kPdfPluginMimeType, "pdf",
  137. "Portable Document Format");
  138. pdf_info.mime_types.push_back(pdf_mime_type);
  139. pdf_info.internal_entry_points.get_interface = chrome_pdf::PPP_GetInterface;
  140. pdf_info.internal_entry_points.initialize_module =
  141. chrome_pdf::PPP_InitializeModule;
  142. pdf_info.internal_entry_points.shutdown_module =
  143. chrome_pdf::PPP_ShutdownModule;
  144. pdf_info.permissions = ppapi::PERMISSION_PRIVATE | ppapi::PERMISSION_DEV;
  145. plugins->push_back(pdf_info);
  146. #endif // BUILDFLAG(ENABLE_PDF_VIEWER)
  147. }
  148. #endif // BUILDFLAG(ENABLE_PLUGINS)
  149. void AppendDelimitedSwitchToVector(const base::StringPiece cmd_switch,
  150. std::vector<std::string>* append_me) {
  151. auto* command_line = base::CommandLine::ForCurrentProcess();
  152. auto switch_value = command_line->GetSwitchValueASCII(cmd_switch);
  153. if (!switch_value.empty()) {
  154. constexpr base::StringPiece delimiter(",", 1);
  155. auto tokens =
  156. base::SplitString(switch_value, delimiter, base::TRIM_WHITESPACE,
  157. base::SPLIT_WANT_NONEMPTY);
  158. append_me->reserve(append_me->size() + tokens.size());
  159. std::move(std::begin(tokens), std::end(tokens),
  160. std::back_inserter(*append_me));
  161. }
  162. }
  163. } // namespace
  164. AtomContentClient::AtomContentClient() {}
  165. AtomContentClient::~AtomContentClient() {}
  166. base::string16 AtomContentClient::GetLocalizedString(int message_id) {
  167. return l10n_util::GetStringUTF16(message_id);
  168. }
  169. base::StringPiece AtomContentClient::GetDataResource(
  170. int resource_id,
  171. ui::ScaleFactor scale_factor) {
  172. return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
  173. resource_id, scale_factor);
  174. }
  175. gfx::Image& AtomContentClient::GetNativeImageNamed(int resource_id) {
  176. return ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(
  177. resource_id);
  178. }
  179. base::RefCountedMemory* AtomContentClient::GetDataResourceBytes(
  180. int resource_id) {
  181. return ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
  182. resource_id);
  183. }
  184. void AtomContentClient::AddAdditionalSchemes(Schemes* schemes) {
  185. AppendDelimitedSwitchToVector(switches::kServiceWorkerSchemes,
  186. &schemes->service_worker_schemes);
  187. AppendDelimitedSwitchToVector(switches::kStandardSchemes,
  188. &schemes->standard_schemes);
  189. AppendDelimitedSwitchToVector(switches::kSecureSchemes,
  190. &schemes->secure_schemes);
  191. AppendDelimitedSwitchToVector(switches::kBypassCSPSchemes,
  192. &schemes->csp_bypassing_schemes);
  193. AppendDelimitedSwitchToVector(switches::kCORSSchemes,
  194. &schemes->cors_enabled_schemes);
  195. schemes->service_worker_schemes.push_back(url::kFileScheme);
  196. schemes->standard_schemes.push_back("chrome-extension");
  197. }
  198. void AtomContentClient::AddPepperPlugins(
  199. std::vector<content::PepperPluginInfo>* plugins) {
  200. #if BUILDFLAG(ENABLE_PEPPER_FLASH)
  201. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  202. AddPepperFlashFromCommandLine(command_line, plugins);
  203. #endif // BUILDFLAG(ENABLE_PEPPER_FLASH)
  204. #if BUILDFLAG(ENABLE_PLUGINS)
  205. ComputeBuiltInPlugins(plugins);
  206. #endif // BUILDFLAG(ENABLE_PLUGINS)
  207. }
  208. void AtomContentClient::AddContentDecryptionModules(
  209. std::vector<content::CdmInfo>* cdms,
  210. std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
  211. if (cdms) {
  212. #if defined(WIDEVINE_CDM_AVAILABLE)
  213. base::FilePath cdm_path;
  214. std::vector<media::VideoCodec> video_codecs_supported;
  215. base::flat_set<media::CdmSessionType> session_types_supported;
  216. base::flat_set<media::EncryptionMode> encryption_modes_supported;
  217. if (IsWidevineAvailable(&cdm_path, &video_codecs_supported,
  218. &session_types_supported,
  219. &encryption_modes_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. content::CdmCapability capability(
  229. video_codecs_supported, encryption_modes_supported,
  230. session_types_supported, base::flat_set<media::CdmProxy::Protocol>());
  231. cdms->push_back(content::CdmInfo(
  232. kWidevineCdmDisplayName, kWidevineCdmGuid, version, cdm_path,
  233. kWidevineCdmFileSystemId, capability, kWidevineKeySystem, false));
  234. }
  235. #endif // defined(WIDEVINE_CDM_AVAILABLE)
  236. }
  237. }
  238. } // namespace electron