// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/cdm/common/cdm_manifest.h" #include <stddef.h> #include <memory> #include <string> #include <string_view> #include <vector> #include "base/containers/flat_set.h" #include "base/containers/span.h" #include "base/files/file_path.h" #include "base/json/json_file_value_serializer.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/values.h" #include "base/version.h" #include "content/public/common/cdm_info.h" #include "media/base/cdm_capability.h" #include "media/base/content_decryption_module.h" #include "media/base/decrypt_config.h" #include "media/base/video_codecs.h" #include "media/cdm/supported_audio_codecs.h" #include "media/cdm/supported_cdm_versions.h" #include "media/media_buildflags.h" #if !BUILDFLAG(ENABLE_LIBRARY_CDMS) #error This file should only be compiled when library CDMs are enabled #endif namespace { // The CDM manifest includes several custom values, all beginning with "x-cdm-". // They are: // x-cdm-module-versions // x-cdm-interface-versions // x-cdm-host-versions // x-cdm-codecs // x-cdm-persistent-license-support // x-cdm-supported-encryption-schemes // What they represent is listed below. They should never have non-backwards // compatible changes. All values are strings. All values that are lists are // delimited by commas. No trailing commas. For example, "1,2,4". const char kCdmValueDelimiter[] = …; // This field in the manifest is parsed by component updater code (e.g. // `ComponentInstaller::FindPreinstallation()`) as well as in this file. const char kCdmVersion[] = …; // The following entries are required. // Interface versions are lists of integers (e.g. "1" or "1,2,4"). // All match the interface versions from content_decryption_module.h that the // CDM supports. // Matches CDM_MODULE_VERSION. const char kCdmModuleVersionsName[] = …; // Matches supported ContentDecryptionModule_* version(s). const char kCdmInterfaceVersionsName[] = …; // Matches supported Host_* version(s). const char kCdmHostVersionsName[] = …; // The codecs list is a list of simple codec names (e.g. "vp8,vorbis"). const char kCdmCodecsListName[] = …; // Whether persistent license is supported by the CDM: "true" or "false". const char kCdmPersistentLicenseSupportName[] = …; // The list of supported encryption schemes (e.g. ["cenc","cbcs"]). const char kCdmSupportedEncryptionSchemesName[] = …; // The following strings are used to specify supported codecs in the // parameter |kCdmCodecsListName|. const char kCdmSupportedCodecVp8[] = …; // Supports at least VP9 profile 0 and profile 2. const char kCdmSupportedCodecVp9[] = …; const char kCdmSupportedCodecAv1[] = …; #if BUILDFLAG(USE_PROPRIETARY_CODECS) const char kCdmSupportedCodecAvc1[] = "avc1"; #endif // The following strings are used to specify supported encryption schemes in // the parameter |kCdmSupportedEncryptionSchemesName|. const char kCdmSupportedEncryptionSchemeCenc[] = …; const char kCdmSupportedEncryptionSchemeCbcs[] = …; VersionCheckFunc; // Returns whether the CDM's API version, as specified in the manifest by // |version_name|, is supported in this Chrome binary and not disabled at run // time by calling |version_check_func|. If the manifest entry contains multiple // values, each one is checked sequentially, and if any one is supported, this // function returns true. If all values in the manifest entry are not supported, // then return false. bool CheckForCompatibleVersion(const base::Value::Dict& manifest, const std::string version_name, VersionCheckFunc version_check_func) { … } // Returns true and updates |encryption_schemes| if the appropriate manifest // entry is valid. Returns false and does not modify |encryption_schemes| if the // manifest entry is incorrectly formatted. It is assumed that all CDMs support // 'cenc', so if the manifest entry is missing, the result will indicate support // for 'cenc' only. Incorrect types in the manifest entry will log the error and // fail. Unrecognized values will be reported but otherwise ignored. bool GetEncryptionSchemes( const base::Value::Dict& manifest, base::flat_set<media::EncryptionScheme>* encryption_schemes) { … } // Returns true and updates |audio_codecs| with the full set of audio // codecs that support decryption. bool GetAudioCodecs(const base::Value::Dict& manifest, base::flat_set<media::AudioCodec>* audio_codecs) { … } // Returns true and updates |video_codecs| if the appropriate manifest entry is // valid. Returns false and does not modify |video_codecs| if the manifest entry // is incorrectly formatted. bool GetVideoCodecs(const base::Value::Dict& manifest, media::CdmCapability::VideoCodecMap* video_codecs) { … } // Returns true and updates |session_types| if the appropriate manifest entry is // valid. Returns false if the manifest entry is incorrectly formatted. bool GetSessionTypes(const base::Value::Dict& manifest, base::flat_set<media::CdmSessionType>* session_types) { … } bool GetVersion(const base::Value::Dict& manifest, base::Version* version) { … } } // namespace bool IsCdmManifestCompatibleWithChrome(const base::Value::Dict& manifest) { … } bool ParseCdmManifest(const base::Value::Dict& manifest, media::CdmCapability* capability) { … } bool ParseCdmManifestFromPath(const base::FilePath& manifest_path, base::Version* version, media::CdmCapability* capability) { … }