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