| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chrome/browser/component_updater/widevine_cdm_component_installer.h" | 5 #include "chrome/browser/component_updater/widevine_cdm_component_installer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <utility> | 11 #include <utility> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/base_paths.h" | 14 #include "base/base_paths.h" |
| 15 #include "base/bind.h" | 15 #include "base/bind.h" |
| 16 #include "base/files/file_path.h" | 16 #include "base/files/file_path.h" |
| 17 #include "base/files/file_util.h" | 17 #include "base/files/file_util.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
| 21 #include "base/strings/string16.h" | 21 #include "base/strings/string16.h" |
| 22 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
| 23 #include "base/strings/string_split.h" | 23 #include "base/strings/string_split.h" |
| 24 #include "base/strings/string_util.h" |
| 24 #include "base/strings/utf_string_conversions.h" | 25 #include "base/strings/utf_string_conversions.h" |
| 25 #include "base/values.h" | 26 #include "base/values.h" |
| 26 #include "build/build_config.h" | 27 #include "build/build_config.h" |
| 27 #include "chrome/common/chrome_paths.h" | 28 #include "chrome/common/chrome_paths.h" |
| 28 #include "chrome/common/widevine_cdm_constants.h" | 29 #include "chrome/common/widevine_cdm_constants.h" |
| 29 #include "components/component_updater/component_updater_service.h" | 30 #include "components/component_updater/component_updater_service.h" |
| 30 #include "components/component_updater/default_component_installer.h" | 31 #include "components/component_updater/default_component_installer.h" |
| 31 #include "components/version_info/version_info.h" | 32 #include "components/version_info/version_info.h" |
| 32 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
| 34 #include "content/public/browser/cdm_service.h" |
| 33 #include "content/public/browser/plugin_service.h" | 35 #include "content/public/browser/plugin_service.h" |
| 36 #include "content/public/common/cdm_info.h" |
| 34 #include "content/public/common/pepper_plugin_info.h" | 37 #include "content/public/common/pepper_plugin_info.h" |
| 35 #include "media/cdm/supported_cdm_versions.h" | 38 #include "media/cdm/supported_cdm_versions.h" |
| 36 #include "third_party/widevine/cdm/widevine_cdm_common.h" | 39 #include "third_party/widevine/cdm/widevine_cdm_common.h" |
| 37 | 40 |
| 38 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. NOLINT | 41 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. NOLINT |
| 39 | 42 |
| 40 using content::BrowserThread; | 43 using content::BrowserThread; |
| 44 using content::CdmService; |
| 41 using content::PluginService; | 45 using content::PluginService; |
| 42 | 46 |
| 43 namespace component_updater { | 47 namespace component_updater { |
| 44 | 48 |
| 45 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) | 49 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) |
| 46 | 50 |
| 47 namespace { | 51 namespace { |
| 48 | 52 |
| 49 // CRX hash. The extension id is: oimompecagnajdejgnnjijobebaeigek. | 53 // CRX hash. The extension id is: oimompecagnajdejgnnjijobebaeigek. |
| 50 const uint8_t kSha2Hash[] = {0xe8, 0xce, 0xcf, 0x42, 0x06, 0xd0, 0x93, 0x49, | 54 const uint8_t kSha2Hash[] = {0xe8, 0xce, 0xcf, 0x42, 0x06, 0xd0, 0x93, 0x49, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 // Widevine CDM is packaged as a multi-CRX. Widevine CDM binaries are located in | 105 // Widevine CDM is packaged as a multi-CRX. Widevine CDM binaries are located in |
| 102 // _platform_specific/<platform_arch> folder in the package. This function | 106 // _platform_specific/<platform_arch> folder in the package. This function |
| 103 // returns the platform-specific subdirectory that is part of that multi-CRX. | 107 // returns the platform-specific subdirectory that is part of that multi-CRX. |
| 104 base::FilePath GetPlatformDirectory(const base::FilePath& base_path) { | 108 base::FilePath GetPlatformDirectory(const base::FilePath& base_path) { |
| 105 std::string platform_arch = kWidevineCdmPlatform; | 109 std::string platform_arch = kWidevineCdmPlatform; |
| 106 platform_arch += '_'; | 110 platform_arch += '_'; |
| 107 platform_arch += kWidevineCdmArch; | 111 platform_arch += kWidevineCdmArch; |
| 108 return base_path.AppendASCII("_platform_specific").AppendASCII(platform_arch); | 112 return base_path.AppendASCII("_platform_specific").AppendASCII(platform_arch); |
| 109 } | 113 } |
| 110 | 114 |
| 111 bool MakeWidevineCdmPluginInfo( | 115 bool MakeWidevineCdmPluginInfo(const base::Version& version, |
| 112 const base::Version& version, | 116 const base::FilePath& cdm_install_dir, |
| 113 const base::FilePath& path, | 117 const std::string& codecs, |
| 114 const std::vector<base::string16>& additional_param_names, | 118 content::PepperPluginInfo* plugin_info) { |
| 115 const std::vector<base::string16>& additional_param_values, | |
| 116 content::PepperPluginInfo* plugin_info) { | |
| 117 if (!version.IsValid() || | 119 if (!version.IsValid() || |
| 118 version.components().size() != | 120 version.components().size() != |
| 119 static_cast<size_t>(kWidevineCdmVersionNumComponents)) { | 121 static_cast<size_t>(kWidevineCdmVersionNumComponents)) { |
| 120 return false; | 122 return false; |
| 121 } | 123 } |
| 122 | 124 |
| 123 plugin_info->is_internal = false; | 125 plugin_info->is_internal = false; |
| 124 // Widevine CDM must run out of process. | 126 // Widevine CDM must run out of process. |
| 125 plugin_info->is_out_of_process = true; | 127 plugin_info->is_out_of_process = true; |
| 126 plugin_info->path = path; | 128 plugin_info->path = GetPlatformDirectory(cdm_install_dir) |
| 129 .AppendASCII(kWidevineCdmAdapterFileName); |
| 127 plugin_info->name = kWidevineCdmDisplayName; | 130 plugin_info->name = kWidevineCdmDisplayName; |
| 128 plugin_info->description = kWidevineCdmDescription + | 131 plugin_info->description = kWidevineCdmDescription + |
| 129 std::string(" (version: ") + version.GetString() + | 132 std::string(" (version: ") + version.GetString() + |
| 130 ")"; | 133 ")"; |
| 131 plugin_info->version = version.GetString(); | 134 plugin_info->version = version.GetString(); |
| 132 content::WebPluginMimeType widevine_cdm_mime_type( | 135 content::WebPluginMimeType widevine_cdm_mime_type( |
| 133 kWidevineCdmPluginMimeType, | 136 kWidevineCdmPluginMimeType, |
| 134 kWidevineCdmPluginExtension, | 137 kWidevineCdmPluginExtension, |
| 135 kWidevineCdmPluginMimeTypeDescription); | 138 kWidevineCdmPluginMimeTypeDescription); |
| 136 widevine_cdm_mime_type.additional_param_names = additional_param_names; | 139 widevine_cdm_mime_type.additional_param_names.push_back( |
| 137 widevine_cdm_mime_type.additional_param_values = additional_param_values; | 140 base::ASCIIToUTF16(kCdmSupportedCodecsParamName)); |
| 141 widevine_cdm_mime_type.additional_param_values.push_back( |
| 142 base::ASCIIToUTF16(codecs)); |
| 143 |
| 138 plugin_info->mime_types.push_back(widevine_cdm_mime_type); | 144 plugin_info->mime_types.push_back(widevine_cdm_mime_type); |
| 139 plugin_info->permissions = kWidevineCdmPluginPermissions; | 145 plugin_info->permissions = kWidevineCdmPluginPermissions; |
| 140 | 146 |
| 141 return true; | 147 return true; |
| 142 } | 148 } |
| 143 | 149 |
| 144 typedef bool (*VersionCheckFunc)(int version); | 150 typedef bool (*VersionCheckFunc)(int version); |
| 145 | 151 |
| 146 bool CheckForCompatibleVersion(const base::DictionaryValue& manifest, | 152 bool CheckForCompatibleVersion(const base::DictionaryValue& manifest, |
| 147 const std::string version_name, | 153 const std::string version_name, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 178 kCdmModuleVersionsName, | 184 kCdmModuleVersionsName, |
| 179 media::IsSupportedCdmModuleVersion) && | 185 media::IsSupportedCdmModuleVersion) && |
| 180 CheckForCompatibleVersion(manifest, | 186 CheckForCompatibleVersion(manifest, |
| 181 kCdmInterfaceVersionsName, | 187 kCdmInterfaceVersionsName, |
| 182 media::IsSupportedCdmInterfaceVersion) && | 188 media::IsSupportedCdmInterfaceVersion) && |
| 183 CheckForCompatibleVersion(manifest, | 189 CheckForCompatibleVersion(manifest, |
| 184 kCdmHostVersionsName, | 190 kCdmHostVersionsName, |
| 185 media::IsSupportedCdmHostVersion); | 191 media::IsSupportedCdmHostVersion); |
| 186 } | 192 } |
| 187 | 193 |
| 188 void GetAdditionalParams(const base::DictionaryValue& manifest, | 194 std::string GetCodecs(const base::DictionaryValue& manifest) { |
| 189 std::vector<base::string16>* additional_param_names, | 195 std::string codecs; |
| 190 std::vector<base::string16>* additional_param_values) { | 196 if (manifest.GetStringASCII(kCdmCodecsListName, &codecs)) { |
| 191 base::string16 codecs; | |
| 192 if (manifest.GetString(kCdmCodecsListName, &codecs)) { | |
| 193 DLOG_IF(WARNING, codecs.empty()) | 197 DLOG_IF(WARNING, codecs.empty()) |
| 194 << "Widevine CDM component manifest has empty codecs list"; | 198 << "Widevine CDM component manifest has empty codecs list"; |
| 195 additional_param_names->push_back( | |
| 196 base::ASCIIToUTF16(kCdmSupportedCodecsParamName)); | |
| 197 additional_param_values->push_back(codecs); | |
| 198 } else { | 199 } else { |
| 199 DLOG(WARNING) << "Widevine CDM component manifest is missing codecs"; | 200 DLOG(WARNING) << "Widevine CDM component manifest is missing codecs"; |
| 200 } | 201 } |
| 202 return codecs; |
| 201 } | 203 } |
| 202 | 204 |
| 203 void RegisterWidevineCdmWithChrome( | 205 void RegisterWidevineCdmWithChrome( |
| 204 const base::Version& cdm_version, | 206 const base::Version& cdm_version, |
| 205 const base::FilePath& adapter_install_path, | 207 const base::FilePath& cdm_install_dir, |
| 206 std::unique_ptr<base::DictionaryValue> manifest) { | 208 std::unique_ptr<base::DictionaryValue> manifest) { |
| 207 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 209 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 208 std::vector<base::string16> additional_param_names; | 210 const std::string codecs = GetCodecs(*manifest); |
| 209 std::vector<base::string16> additional_param_values; | 211 |
| 210 GetAdditionalParams( | |
| 211 *manifest, &additional_param_names, &additional_param_values); | |
| 212 content::PepperPluginInfo plugin_info; | 212 content::PepperPluginInfo plugin_info; |
| 213 if (!MakeWidevineCdmPluginInfo(cdm_version, | 213 if (!MakeWidevineCdmPluginInfo(cdm_version, cdm_install_dir, codecs, |
| 214 adapter_install_path, | |
| 215 additional_param_names, | |
| 216 additional_param_values, | |
| 217 &plugin_info)) { | 214 &plugin_info)) { |
| 218 return; | 215 return; |
| 219 } | 216 } |
| 220 | 217 |
| 221 // true = Add to beginning of list to override any existing registrations. | 218 // true = Add to beginning of list to override any existing registrations. |
| 222 PluginService::GetInstance()->RegisterInternalPlugin( | 219 PluginService::GetInstance()->RegisterInternalPlugin( |
| 223 plugin_info.ToWebPluginInfo(), true); | 220 plugin_info.ToWebPluginInfo(), true); |
| 224 // Tell the browser to refresh the plugin list. Then tell all renderers to | 221 // Tell the browser to refresh the plugin list. Then tell all renderers to |
| 225 // update their plugin list caches. | 222 // update their plugin list caches. |
| 226 PluginService::GetInstance()->RefreshPlugins(); | 223 PluginService::GetInstance()->RefreshPlugins(); |
| 227 PluginService::GetInstance()->PurgePluginListCache(NULL, false); | 224 PluginService::GetInstance()->PurgePluginListCache(NULL, false); |
| 225 |
| 226 // Also register Widevine with the CdmService. |
| 227 const base::FilePath cdm_path = |
| 228 GetPlatformDirectory(cdm_install_dir).AppendASCII(kWidevineCdmFileName); |
| 229 const std::vector<std::string> supported_codecs = base::SplitString( |
| 230 codecs, std::string(1, kCdmSupportedCodecsValueDelimiter), |
| 231 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| 232 CdmService::GetInstance()->RegisterCdm(content::CdmInfo( |
| 233 kWidevineCdmType, cdm_version, cdm_path, supported_codecs)); |
| 228 } | 234 } |
| 229 | 235 |
| 230 } // namespace | 236 } // namespace |
| 231 | 237 |
| 232 class WidevineCdmComponentInstallerTraits : public ComponentInstallerTraits { | 238 class WidevineCdmComponentInstallerTraits : public ComponentInstallerTraits { |
| 233 public: | 239 public: |
| 234 WidevineCdmComponentInstallerTraits(); | 240 WidevineCdmComponentInstallerTraits(); |
| 235 ~WidevineCdmComponentInstallerTraits() override {} | 241 ~WidevineCdmComponentInstallerTraits() override {} |
| 236 | 242 |
| 237 private: | 243 private: |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 } | 363 } |
| 358 | 364 |
| 359 base::FilePath adapter_source_path; | 365 base::FilePath adapter_source_path; |
| 360 PathService::Get(chrome::FILE_WIDEVINE_CDM_ADAPTER, &adapter_source_path); | 366 PathService::Get(chrome::FILE_WIDEVINE_CDM_ADAPTER, &adapter_source_path); |
| 361 if (!base::CopyFile(adapter_source_path, adapter_install_path)) { | 367 if (!base::CopyFile(adapter_source_path, adapter_install_path)) { |
| 362 PLOG(WARNING) << "Failed to copy Widevine CDM adapter."; | 368 PLOG(WARNING) << "Failed to copy Widevine CDM adapter."; |
| 363 return; | 369 return; |
| 364 } | 370 } |
| 365 } | 371 } |
| 366 | 372 |
| 367 BrowserThread::PostTask(content::BrowserThread::UI, | 373 BrowserThread::PostTask( |
| 368 FROM_HERE, | 374 content::BrowserThread::UI, FROM_HERE, |
| 369 base::Bind(&RegisterWidevineCdmWithChrome, | 375 base::Bind(&RegisterWidevineCdmWithChrome, cdm_version, cdm_install_dir, |
| 370 cdm_version, | 376 base::Passed(&manifest))); |
| 371 adapter_install_path, | |
| 372 base::Passed(&manifest))); | |
| 373 } | 377 } |
| 374 | 378 |
| 375 #endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) | 379 #endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) |
| 376 | 380 |
| 377 void RegisterWidevineCdmComponent(ComponentUpdateService* cus) { | 381 void RegisterWidevineCdmComponent(ComponentUpdateService* cus) { |
| 378 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) | 382 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) |
| 379 base::FilePath adapter_source_path; | 383 base::FilePath adapter_source_path; |
| 380 PathService::Get(chrome::FILE_WIDEVINE_CDM_ADAPTER, &adapter_source_path); | 384 PathService::Get(chrome::FILE_WIDEVINE_CDM_ADAPTER, &adapter_source_path); |
| 381 if (!base::PathExists(adapter_source_path)) | 385 if (!base::PathExists(adapter_source_path)) |
| 382 return; | 386 return; |
| 383 std::unique_ptr<ComponentInstallerTraits> traits( | 387 std::unique_ptr<ComponentInstallerTraits> traits( |
| 384 new WidevineCdmComponentInstallerTraits); | 388 new WidevineCdmComponentInstallerTraits); |
| 385 // |cus| will take ownership of |installer| during installer->Register(cus). | 389 // |cus| will take ownership of |installer| during installer->Register(cus). |
| 386 DefaultComponentInstaller* installer = | 390 DefaultComponentInstaller* installer = |
| 387 new DefaultComponentInstaller(std::move(traits)); | 391 new DefaultComponentInstaller(std::move(traits)); |
| 388 installer->Register(cus, base::Closure()); | 392 installer->Register(cus, base::Closure()); |
| 389 #endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) | 393 #endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) |
| 390 } | 394 } |
| 391 | 395 |
| 392 } // namespace component_updater | 396 } // namespace component_updater |
| OLD | NEW |