diff --git a/components/cdm/browser/media_drm_storage_impl.cc b/components/cdm/browser/media_drm_storage_impl.cc index bbc6d91bfbf67335503a3c51cf85f03cea186b90..ec3406ab0ab8641e605d9be9473ae77b285be46d 100644 --- a/components/cdm/browser/media_drm_storage_impl.cc +++ b/components/cdm/browser/media_drm_storage_impl.cc @@ -439,16 +439,18 @@ bool SessionsModifiedBetween(const base::Value::Dict& sessions_dict, base::UnguessableToken GetOriginIdForOrigin( const base::Value::Dict& storage_dict, const url::Origin& origin) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", origin: " << origin; const base::Value::Dict* origin_dict = storage_dict.FindDict(origin.Serialize()); - if (!origin_dict) + if (!origin_dict) { + LOG(INFO) << "[NEU][CDM]" << __func__; return base::UnguessableToken::Null(); - + } std::unique_ptr origin_data = OriginData::FromDictValue(*origin_dict); if (!origin_data) return base::UnguessableToken::Null(); - + LOG(INFO) << "[NEU][CDM]" << __func__; // |origin_id| can be empty even if |origin_dict| exists. This can happen // if |origin_dict| was created with an old version of Chrome. return origin_data->origin_id(); @@ -495,6 +497,7 @@ class InitializationSerializer { const url::Origin& origin, MediaDrmStorageImpl::GetOriginIdCB get_origin_id_cb, MediaDrmStorageImpl::OriginIdObtainedCB origin_id_obtained_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__<< " origin: " << origin; DVLOG(3) << __func__ << " origin: " << origin; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -504,12 +507,13 @@ class InitializationSerializer { base::UnguessableToken origin_id = GetOriginIdForOrigin(storage_dict, origin); if (origin_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(3) << __func__ << ": Found origin ID in pref service dictionary: " << origin_id; std::move(origin_id_obtained_cb).Run(true, origin_id); return; } - + LOG(INFO) << "[NEU][CDM]" << __func__; // No origin ID found, so check if another Initialize() call is in progress. PreferenceAndOriginKey key{pref_service, origin}; auto entry = pending_requests_.find(key); @@ -519,21 +523,23 @@ class InitializationSerializer { entry->second.emplace_back(std::move(origin_id_obtained_cb)); return; } - + LOG(INFO) << "[NEU][CDM]" << __func__; // Entry does not exist, so create a new one. std::vector origin_id_obtained_cb_list; origin_id_obtained_cb_list.emplace_back(std::move(origin_id_obtained_cb)); pending_requests_.emplace(key, std::move(origin_id_obtained_cb_list)); - + LOG(INFO) << "[NEU][CDM]" << __func__; // Now call |get_origin_id_cb|. It will call OnOriginIdObtained() when done, // which will call all the callbacks saved for this preference and origin // pair. Use of base::Unretained() is valid as |this| is a singleton stored // in a static variable. DVLOG(3) << __func__ << ": Call |get_origin_id_cb| to get origin ID."; + LOG(INFO) << "[NEU][CDM]" << __func__; get_origin_id_cb.Run( base::BindOnce(&InitializationSerializer::OnOriginIdObtained, base::Unretained(this), pref_service, origin)); + LOG(INFO) << "[NEU][CDM]" << __func__; } private: @@ -542,6 +548,7 @@ class InitializationSerializer { const url::Origin& origin, bool success, const MediaDrmStorageImpl::MediaDrmOriginId& origin_id) { + LOG(INFO) << "[NEU][CDM]" << __func__ << " origin: " << origin; DVLOG(3) << __func__ << " origin: " << origin; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -551,7 +558,7 @@ class InitializationSerializer { CreateOriginDictAndReturnSessionsDict(update.Get(), origin, origin_id.value()); } - + LOG(INFO) << "[NEU][CDM]" << __func__ << " origin: " << origin; // Now call any callbacks waiting for this origin ID to be allocated. auto entry = pending_requests_.find({pref_service, origin}); DCHECK(entry != pending_requests_.end()); @@ -559,7 +566,7 @@ class InitializationSerializer { std::vector callbacks; callbacks.swap(entry->second); pending_requests_.erase(entry); - + LOG(INFO) << "[NEU][CDM]" << __func__ << " origin: " << origin; for (auto& callback : callbacks) std::move(callback).Run(success, origin_id); } @@ -577,6 +584,7 @@ class InitializationSerializer { // static void MediaDrmStorageImpl::RegisterProfilePrefs(PrefRegistrySimple* registry) { + LOG(INFO) << "[NEU][CDM]" << __func__; registry->RegisterDictionaryPref(prefs::kMediaDrmStorage); } @@ -723,14 +731,17 @@ MediaDrmStorageImpl::~MediaDrmStorageImpl() { } void MediaDrmStorageImpl::Initialize(InitializeCallback callback) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__ << ": origin = " << origin(); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!init_cb_); if (is_initialized_) { std::move(callback).Run(true, origin_id_); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(!origin_id_); // Call using SerializeInitializeRequests() to handle the case where @@ -748,19 +759,22 @@ void MediaDrmStorageImpl::Initialize(InitializeCallback callback) { void MediaDrmStorageImpl::OnOriginIdObtained( bool success, const MediaDrmOriginId& origin_id) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", success: " << success; is_initialized_ = true; if (!success) { // Unable to get a pre-provisioned origin ID, so call // |allow_empty_origin_id_cb_| to see if the empty origin ID is allowed. + LOG(INFO) << "[NEU][CDM]" << __func__; allow_empty_origin_id_cb_.Run( base::BindOnce(&MediaDrmStorageImpl::OnEmptyOriginIdAllowed, weak_factory_.GetWeakPtr())); return; } - + LOG(INFO) << "[NEU][CDM]" << __func__; origin_id_ = origin_id; std::move(init_cb_).Run(success, origin_id_); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MediaDrmStorageImpl::OnEmptyOriginIdAllowed(bool allowed) { @@ -798,6 +812,7 @@ void MediaDrmStorageImpl::SavePersistentSession( const std::string& session_id, media::mojom::SessionDataPtr session_data, SavePersistentSessionCallback callback) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); diff --git a/components/cdm/common/BUILD.gn b/components/cdm/common/BUILD.gn index 373ce6c6f41905104ce5655eaf67c67d556d998c..8ef351ba0c4cfdb12448e90c90e468d059f394f6 100644 --- a/components/cdm/common/BUILD.gn +++ b/components/cdm/common/BUILD.gn @@ -20,6 +20,13 @@ static_library("common") { ] } + if (defined(ohos_enable_cdm) && ohos_enable_cdm) { + sources += [ + "widevine_drm_delegate_ohos.cc", + "widevine_drm_delegate_ohos.h", + ] + } + deps = [ "//base", "//content/public/common", diff --git a/components/cdm/common/widevine_drm_delegate_ohos.cc b/components/cdm/common/widevine_drm_delegate_ohos.cc new file mode 100644 index 0000000000000000000000000000000000000000..a8d5a4c0a548e7464125577605f6fc82ae733627 --- /dev/null +++ b/components/cdm/common/widevine_drm_delegate_ohos.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/cdm/common/widevine_drm_delegate_ohos.h" + +#include "base/logging.h" +#include "media/cdm/cenc_utils.h" + +namespace cdm { + +namespace { + +const uint8_t kWidevineUuid[16] = { + 0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE, // + 0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED}; +} // namespace + +WidevineDrmDelegateOHOS::WidevineDrmDelegateOHOS() {} + +WidevineDrmDelegateOHOS::~WidevineDrmDelegateOHOS() {} + +const std::vector WidevineDrmDelegateOHOS::GetUUID() const { + return std::vector(kWidevineUuid, + kWidevineUuid + std::size(kWidevineUuid)); +} + +bool WidevineDrmDelegateOHOS::OnCreateSession( + const media::EmeInitDataType init_data_type, + const std::vector& init_data, + std::vector* init_data_out, + std::vector* /* optional_parameters_out */) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (init_data_type != media::EmeInitDataType::CENC) { + LOG(INFO) << "[NEU][CDM]" << __func__; + return true; + } + LOG(INFO) << "[NEU][CDM]" << __func__; + return media::GetPsshData(init_data, GetUUID(), init_data_out); +} + +} // namespace cdm diff --git a/components/cdm/common/widevine_drm_delegate_ohos.h b/components/cdm/common/widevine_drm_delegate_ohos.h new file mode 100644 index 0000000000000000000000000000000000000000..f89341d676f1740e5557d4b1ff5227fd5ed529b9 --- /dev/null +++ b/components/cdm/common/widevine_drm_delegate_ohos.h @@ -0,0 +1,33 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CDM_COMMON_WIDEVINE_DRM_DELEGATE_OHOS_H_ +#define COMPONENTS_CDM_COMMON_WIDEVINE_DRM_DELEGATE_OHOS_H_ + +#include + +#include "media/base/ohos/ohos_media_drm_bridge_delegate.h" + +namespace cdm { + +class WidevineDrmDelegateOHOS : public media::OHOSMediaDrmBridgeDelegate { + public: + WidevineDrmDelegateOHOS(); + + WidevineDrmDelegateOHOS(const WidevineDrmDelegateOHOS&) = delete; + WidevineDrmDelegateOHOS& operator=(const WidevineDrmDelegateOHOS&) = delete; + + ~WidevineDrmDelegateOHOS() override; + + const std::vector GetUUID() const override; + bool OnCreateSession( + const media::EmeInitDataType init_data_type, + const std::vector& init_data, + std::vector* init_data_out, + std::vector* optional_parameters_out) override; +}; + +} // namespace cdm + +#endif // COMPONENTS_CDM_COMMON_WIDEVINE_DRM_DELEGATE_OHOS_H_ diff --git a/components/cdm/renderer/key_system_support_update.cc b/components/cdm/renderer/key_system_support_update.cc index 52dd9fca98dfb5970c74fb8fd1a153fdf7725bee..c92bd646765597550f1dfa372cadb98ef1741222 100644 --- a/components/cdm/renderer/key_system_support_update.cc +++ b/components/cdm/renderer/key_system_support_update.cc @@ -257,7 +257,9 @@ bool CanSupportPersistentLicense() { // we assume that it can and will make use of persistence no matter whether // persistence-based features are supported or not. return true; - +#elif BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + LOG(INFO) << "[NEU][CDM]" << __func__; + return true; #elif BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) && \ BUILDFLAG(ENABLE_CDM_STORAGE_ID) // On other platforms, persistent licenses are only supported if CDM host @@ -288,6 +290,7 @@ base::flat_set UpdatePersistentLicenseSupport( void AddWidevine(const media::mojom::KeySystemCapabilityPtr& capability, bool can_persist_data, KeySystemInfos* key_systems) { + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(IS_ANDROID) // When using MediaDrm, we assume it'll always try to persist some data. // If we are in incognito mode and MediaDrm were to persist data, we are @@ -360,7 +363,7 @@ void AddWidevine(const media::mojom::KeySystemCapabilityPtr& capability, return; } #endif // BUILDFLAG(IS_ANDROID) - + LOG(INFO) << "[NEU][CDM]" << __func__; // Robustness. using Robustness = WidevineKeySystemInfo::Robustness; auto max_audio_robustness = Robustness::SW_SECURE_CRYPTO; @@ -379,6 +382,9 @@ void AddWidevine(const media::mojom::KeySystemCapabilityPtr& capability, // On Android we support hardware secure if possible. max_audio_robustness = Robustness::HW_SECURE_CRYPTO; max_video_robustness = Robustness::HW_SECURE_ALL; +#elif BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + max_audio_robustness = Robustness::SW_SECURE_DECODE; + max_video_robustness = Robustness::SW_SECURE_DECODE; #else // The hardware secure robustness for the two keys systems are guarded by // different flags. The audio and video robustness should be set differently @@ -407,14 +413,17 @@ void AddWidevine(const media::mojom::KeySystemCapabilityPtr& capability, // persistence-based features are supported or not. persistent_state_support = EmeFeatureSupport::ALWAYS_ENABLED; distinctive_identifier_support = EmeFeatureSupport::ALWAYS_ENABLED; +#elif BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + persistent_state_support = EmeFeatureSupport::REQUESTABLE; + distinctive_identifier_support = EmeFeatureSupport::NOT_SUPPORTED; #endif - + LOG(INFO) << "[NEU][CDM]" << __func__; key_systems->emplace_back(std::make_unique( codecs, encryption_schemes, session_types, hw_secure_codecs, hw_secure_encryption_schemes, hw_secure_session_types, max_audio_robustness, max_video_robustness, persistent_state_support, distinctive_identifier_support)); - + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(IS_WIN) if (base::FeatureList::IsEnabled( media::kHardwareSecureDecryptionExperiment)) { @@ -543,8 +552,10 @@ void OnKeySystemSupportUpdated( bool can_persist_data, media::GetSupportedKeySystemsCB cb, content::KeySystemCapabilityPtrMap key_system_capabilities) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", can_persist_data: " << can_persist_data; KeySystemInfos key_systems; for (const auto& [key_system, capability] : key_system_capabilities) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", " << key_system.c_str(); #if BUILDFLAG(ENABLE_WIDEVINE) if (key_system == kWidevineKeySystem) { AddWidevine(capability, can_persist_data, &key_systems); @@ -573,14 +584,17 @@ void OnKeySystemSupportUpdated( } cb.Run(std::move(key_systems)); + LOG(INFO) << "[NEU][CDM]" << __func__; } } // namespace void GetSupportedKeySystemsUpdates(bool can_persist_data, media::GetSupportedKeySystemsCB cb) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", can_persist_data: " << can_persist_data; content::ObserveKeySystemSupportUpdate(base::BindRepeating( &OnKeySystemSupportUpdated, can_persist_data, std::move(cb))); + LOG(INFO) << "[NEU][CDM]" << __func__; } } // namespace cdm diff --git a/components/cdm/renderer/widevine_key_system_info.cc b/components/cdm/renderer/widevine_key_system_info.cc index 5d65710f71260305f3686ede41caf12857c75c35..48f7ca4d4912494a9e60e2f3f237fe664ec1cd93 100644 --- a/components/cdm/renderer/widevine_key_system_info.cc +++ b/components/cdm/renderer/widevine_key_system_info.cc @@ -89,6 +89,7 @@ std::string WidevineKeySystemInfo::GetBaseKeySystemName() const { bool WidevineKeySystemInfo::IsSupportedKeySystem( const std::string& key_system) const { + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(IS_WIN) if (is_experimental_) { return key_system == kWidevineExperimentKeySystem; @@ -108,6 +109,7 @@ bool WidevineKeySystemInfo::ShouldUseBaseKeySystemName() const { bool WidevineKeySystemInfo::IsSupportedInitDataType( EmeInitDataType init_data_type) const { + LOG(INFO) << "[NEU][CDM]" << __func__; // Here we assume that support for a container implies support for the // associated initialization data type. KeySystems handles validating // |init_data_type| x |container| pairings. @@ -242,8 +244,10 @@ EmeConfig::Rule WidevineKeySystemInfo::GetRobustnessConfigRule( EmeConfig::Rule WidevineKeySystemInfo::GetPersistentLicenseSessionSupport() const { + LOG(INFO) << "[NEU][CDM]" << __func__; bool is_supported = session_types_.contains(CdmSessionType::kPersistentLicense); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", is_supported: " << is_supported; #if BUILDFLAG(IS_CHROMEOS) // The logic around hardware/software security support is complicated on @@ -263,16 +267,21 @@ EmeConfig::Rule WidevineKeySystemInfo::GetPersistentLicenseSessionSupport() bool is_hw_secure_supported = hw_secure_session_types_.contains(CdmSessionType::kPersistentLicense); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", is_hw_secure_supported: " << is_hw_secure_supported; // Per GetPersistentLicenseSessionSupport() API, there's no need to specify // the PERSISTENCE requirement here, which is implicitly assumed and enforced // by `KeySystemConfigSelector`. if (is_supported && is_hw_secure_supported) { + LOG(INFO) << "[NEU][CDM]" << __func__; return EmeConfig::SupportedRule(); } else if (is_supported && !is_hw_secure_supported) { + LOG(INFO) << "[NEU][CDM]" << __func__; return EmeConfig{.hw_secure_codecs = EmeConfigRuleState::kNotAllowed}; } else if (!is_supported && is_hw_secure_supported) { + LOG(INFO) << "[NEU][CDM]" << __func__; return EmeConfig{.hw_secure_codecs = EmeConfigRuleState::kRequired}; } else { + LOG(INFO) << "[NEU][CDM]" << __func__; return media::EmeConfig::UnsupportedRule(); } #endif // BUILDFLAG(IS_CHROMEOS) diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index b26c54a3c43e1123f8cd84b8f1ea71a48615a143..2eda1e16b25d815d9bd15da26168899761d9ad1b 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -3278,6 +3278,13 @@ source_set("browser") { "media/session/audio_interrupt_adapter_impl.h", ] + if (defined(ohos_enable_cdm) && ohos_enable_cdm) { + sources += [ + "media/key_system_support_ohos.cc", + "media/key_system_support_ohos.h", + ] + } + deps += [ "//ui/accessibility:ax_assistant" ] #if defined(OHOS_PRINT) diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 25bf28ef954f17da71dbae4077598353c1049b0f..6a47a28395ef3f069a3710d4f00af124ed9e78f2 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -178,6 +178,10 @@ #include "ui/gl/gl_surface.h" #endif +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +#include "media/base/ohos/ohos_media_drm_bridge_client.h" +#endif + #if BUILDFLAG(IS_MAC) #include "base/mac/scoped_nsautorelease_pool.h" #include "content/browser/renderer_host/browser_compositor_view_mac.h" @@ -772,7 +776,7 @@ void BrowserMainLoop::CreateMessageLoopForEarlyShutdown() { int BrowserMainLoop::PreCreateThreads() { TRACE_EVENT0("startup", "BrowserMainLoop::PreCreateThreads"); - + LOG(INFO) << "[NEU][CDM]" << __func__; // Make sure no accidental call to initialize GpuDataManager earlier. DCHECK(!GpuDataManagerImpl::Initialized()); if (parts_) { @@ -802,6 +806,11 @@ int BrowserMainLoop::PreCreateThreads() { CdmRegistry::GetInstance()->Init(); #endif +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + CdmRegistry::GetInstance()->Init(); + LOG(INFO) << "[NEU][CDM]" << __func__; +#endif + #if BUILDFLAG(IS_MAC) // The WindowResizeHelper allows the UI thread to wait on specific renderer // and GPU messages from the IO thread. Initializing it before the IO thread @@ -1446,6 +1455,12 @@ void BrowserMainLoop::PostCreateThreadsImpl() { } #endif +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + LOG(INFO) << "[NEU][CDM]" << __func__ << ", SetMediaDrmBridgeClient Start."; + media::SetMediaDrmBridgeClient(GetContentClient()->GetMediaDrmBridgeClient()); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", SetMediaDrmBridgeClient End."; +#endif + #if defined(OHOS_WPT) if (base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)) { FontUniqueNameLookup::GetInstance(); diff --git a/content/browser/media/cdm_registry_impl.cc b/content/browser/media/cdm_registry_impl.cc index 038101e5bfe3d2ca09c10b591f6a54983b51a20b..ba553d0febc443e72f04d72515e11654c091c584 100644 --- a/content/browser/media/cdm_registry_impl.cc +++ b/content/browser/media/cdm_registry_impl.cc @@ -30,7 +30,9 @@ #if BUILDFLAG(IS_ANDROID) #include "content/browser/media/key_system_support_android.h" #endif - +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +#include "content/browser/media/key_system_support_ohos.h" +#endif #if BUILDFLAG(IS_WIN) #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/media/key_system_support_win.h" @@ -42,6 +44,7 @@ namespace content { namespace { bool MatchKeySystem(const CdmInfo& cdm_info, const std::string& key_system) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", key_system: " << key_system.c_str() << ", " << cdm_info.key_system; return cdm_info.key_system == key_system || (cdm_info.supports_sub_key_systems && media::IsSubKeySystemOf(key_system, cdm_info.key_system)); @@ -233,14 +236,17 @@ CdmRegistryImpl::~CdmRegistryImpl() { } void CdmRegistryImpl::Init() { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Let embedders register CDMs. GetContentClient()->AddContentDecryptionModules(&cdms_, nullptr); + LOG(INFO) << "[NEU][CDM]" << __func__; } void CdmRegistryImpl::RegisterCdm(const CdmInfo& info) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__ << ": key_system=" << info.key_system << ", robustness=" << info.robustness << ", status=" << static_cast(info.status); @@ -262,8 +268,11 @@ void CdmRegistryImpl::RegisterCdm(const CdmInfo& info) { // If there are `key_system_capabilities_update_callbacks_` registered, // finalize key system capabilities and notify the callbacks. Otherwise we'll // finalize key system capabilities in `ObserveKeySystemCapabilities()`. - if (!key_system_capabilities_update_callbacks_.empty()) + if (!key_system_capabilities_update_callbacks_.empty()) { + LOG(INFO) << "[NEU][CDM]" << __func__; FinalizeKeySystemCapabilities(); + } + LOG(INFO) << "[NEU][CDM]" << __func__; } void CdmRegistryImpl::SetHardwareSecureCdmStatus(CdmInfo::Status status) { @@ -272,7 +281,7 @@ void CdmRegistryImpl::SetHardwareSecureCdmStatus(CdmInfo::Status status) { DCHECK(status != CdmInfo::Status::kUninitialized && status != CdmInfo::Status::kEnabled && status != CdmInfo::Status::kCommandLineOverridden); - + LOG(INFO) << "[NEU][CDM]" << __func__; bool updated = false; for (auto& cdm_info : cdms_) { if (cdm_info.robustness == CdmInfo::Robustness::kHardwareSecure) { @@ -291,8 +300,10 @@ void CdmRegistryImpl::SetHardwareSecureCdmStatus(CdmInfo::Status status) { // If there are `key_system_capabilities_update_callbacks_` registered, // finalize key system capabilities and notify the callbacks. Otherwise we'll // finalize key system capabilities in `ObserveKeySystemCapabilities()`. - if (!key_system_capabilities_update_callbacks_.empty()) + if (!key_system_capabilities_update_callbacks_.empty()) { + LOG(INFO) << "[NEU][CDM]" << __func__; FinalizeKeySystemCapabilities(); + } } void CdmRegistryImpl::OnGpuInfoUpdate() { @@ -318,7 +329,8 @@ std::unique_ptr CdmRegistryImpl::GetCdmInfo( DVLOG(2) << __func__ << ": key_system=" << key_system << ", robustness=" << robustness; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - + LOG(INFO) << "[NEU][CDM]" << __func__ << ": key_system=" << key_system + << ", robustness=" << robustness; for (const auto& cdm : cdms_) { if (cdm.robustness == robustness && MatchKeySystem(cdm, key_system)) return std::make_unique(cdm); @@ -329,6 +341,7 @@ std::unique_ptr CdmRegistryImpl::GetCdmInfo( void CdmRegistryImpl::ObserveKeySystemCapabilities( KeySystemCapabilitiesUpdateCB cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -346,6 +359,7 @@ void CdmRegistryImpl::ObserveKeySystemCapabilities( } FinalizeKeySystemCapabilities(); + LOG(INFO) << "[NEU][CDM]" << __func__; } std::pair, CdmInfo::Status> @@ -353,6 +367,8 @@ CdmRegistryImpl::GetCapability(const std::string& key_system, CdmInfo::Robustness robustness) { DVLOG(2) << __func__ << ": key_system=" << key_system << ", robustness=" << robustness; + LOG(INFO) << "[NEU][CDM]" << __func__ << ": key_system=" << key_system + << ", robustness=" << robustness; using Status = CdmInfo::Status; if (robustness == CdmInfo::Robustness::kHardwareSecure) { @@ -403,15 +419,17 @@ CdmRegistryImpl::GetCapability(const std::string& key_system, auto cdm_info = GetCdmInfo(key_system, robustness); if (!cdm_info) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", No " << robustness << " decryption CDM registered for " + << key_system; DVLOG(1) << "No " << robustness << " decryption CDM registered for " << key_system; return {absl::nullopt, Status::kEnabled}; } - + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(!(cdm_info->status == Status::kUninitialized && cdm_info->capability)) << "Capability for " << robustness << " " << key_system << " should not have value if uninitialized."; - + LOG(INFO) << "[NEU][CDM]" << __func__; return {cdm_info->capability, cdm_info->status}; } @@ -419,14 +437,16 @@ std::pair, CdmInfo::Status> CdmRegistryImpl::GetFinalCapability(const std::string& key_system, CdmInfo::Robustness robustness) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - + LOG(INFO) << "[NEU][CDM]" << __func__ << ", key_system: " << key_system.c_str(); const auto [capability, status] = GetCapability(key_system, robustness); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", key_system: " << key_system.c_str() << ", status: " << (int32_t)status; DCHECK(status != CdmInfo::Status::kUninitialized); - + LOG(INFO) << "[NEU][CDM]" << __func__ << ", key_system: " << key_system.c_str(); return {IsEnabled(status) ? capability : absl::nullopt, status}; } void CdmRegistryImpl::FinalizeKeySystemCapabilities() { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!key_system_capabilities_.has_value()); @@ -452,11 +472,13 @@ void CdmRegistryImpl::FinalizeKeySystemCapabilities() { // If not empty, we'll handle it in OnCapabilityInitialized(). if (pending_lazy_initializations_.empty()) UpdateAndNotifyKeySystemCapabilities(); + LOG(INFO) << "[NEU][CDM]" << __func__; } void CdmRegistryImpl::AttemptToFinalizeKeySystemCapability( const std::string& key_system, CdmInfo::Robustness robustness) { + LOG(INFO) << "[NEU][CDM]" << __func__; auto cdm_info = GetCdmInfo(key_system, robustness); if (!cdm_info) { DVLOG(1) << "No " << robustness << " CDM registered for " << key_system; @@ -483,6 +505,7 @@ void CdmRegistryImpl::AttemptToFinalizeKeySystemCapability( base::BindPostTaskToCurrentDefault(base::BindOnce( &CdmRegistryImpl::OnCapabilityInitialized, weak_ptr_factory_.GetWeakPtr(), key_system, robustness))); + LOG(INFO) << "[NEU][CDM]" << __func__; } // TODO(xhwang): Find a way to register this as callbacks so we don't have to @@ -491,6 +514,7 @@ void CdmRegistryImpl::LazyInitializeCapability( const std::string& key_system, CdmInfo::Robustness robustness, media::CdmCapabilityCB cdm_capability_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__ << ": key_system=" << key_system << ", robustness=" << robustness; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -514,15 +538,22 @@ void CdmRegistryImpl::LazyInitializeCapability( } #elif BUILDFLAG(IS_ANDROID) GetAndroidCdmCapability(key_system, robustness, std::move(cdm_capability_cb)); +#elif BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + LOG(INFO) << "[NEU][CDM]" << __func__; + GetOHOSCdmCapability(key_system, robustness, std::move(cdm_capability_cb)); #else std::move(cdm_capability_cb).Run(absl::nullopt); #endif + LOG(INFO) << "[NEU][CDM]" << __func__; } void CdmRegistryImpl::OnCapabilityInitialized( const std::string& key_system, const CdmInfo::Robustness robustness, absl::optional cdm_capability) { + LOG(INFO) << "[NEU][CDM]" << __func__<< ": key_system=" << key_system + << ", robustness=" << robustness + << ", cdm_capability=" << (cdm_capability ? "yes" : "no"); DVLOG(1) << __func__ << ": key_system=" << key_system << ", robustness=" << robustness << ", cdm_capability=" << (cdm_capability ? "yes" : "no"); @@ -542,6 +573,7 @@ void CdmRegistryImpl::FinalizeCapability( const CdmInfo::Robustness robustness, absl::optional cdm_capability, CdmInfo::Status status) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", key_system" << key_system; DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(status != CdmInfo::Status::kUninitialized); @@ -567,6 +599,7 @@ void CdmRegistryImpl::FinalizeCapability( itr->status = status; itr->capability = cdm_capability; + LOG(INFO) << "[NEU][CDM]" << __func__; } void CdmRegistryImpl::UpdateAndNotifyKeySystemCapabilities() { @@ -574,7 +607,7 @@ void CdmRegistryImpl::UpdateAndNotifyKeySystemCapabilities() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto key_system_capabilities = GetKeySystemCapabilities(); - + LOG(INFO) << "[NEU][CDM]" << __func__ << ", hasValue: " << key_system_capabilities_.has_value(); if (key_system_capabilities_.has_value() && key_system_capabilities_.value() == key_system_capabilities) { DVLOG(3) << "Same key system capabilities; no need to update"; @@ -586,22 +619,27 @@ void CdmRegistryImpl::UpdateAndNotifyKeySystemCapabilities() { } std::set CdmRegistryImpl::GetSupportedKeySystems() const { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); std::set supported_key_systems; - for (const auto& cdm : cdms_) + for (const auto& cdm : cdms_) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", " << cdm.key_system.c_str(); supported_key_systems.insert(cdm.key_system); - + } + LOG(INFO) << "[NEU][CDM]" << __func__; return supported_key_systems; } KeySystemCapabilities CdmRegistryImpl::GetKeySystemCapabilities() { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); KeySystemCapabilities key_system_capabilities; std::set supported_key_systems = GetSupportedKeySystems(); for (const auto& key_system : supported_key_systems) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", key_system: " << key_system.c_str(); CdmInfo::Status status; media::mojom::KeySystemCapability capability; @@ -617,11 +655,13 @@ KeySystemCapabilities CdmRegistryImpl::GetKeySystemCapabilities() { ReportHardwareSecureCapabilityStatusUMA( key_system, status, base::OptionalToPtr(capability.hw_secure_capability)); - - if (capability.sw_secure_capability || capability.hw_secure_capability) + LOG(INFO) << "[NEU][CDM]" << __func__ << ", key_system: " << key_system.c_str(); + if (capability.sw_secure_capability || capability.hw_secure_capability) { + LOG(INFO) << "[NEU][CDM]" << __func__; key_system_capabilities[key_system] = std::move(capability); + } } - + LOG(INFO) << "[NEU][CDM]" << __func__; return key_system_capabilities; } diff --git a/content/browser/media/frameless_media_interface_proxy.cc b/content/browser/media/frameless_media_interface_proxy.cc index bb86697b6af9acb2c2e60c2990aed1dc839ef669..139ba8e462de4a999ea5f0bca8edf21b22207df0 100644 --- a/content/browser/media/frameless_media_interface_proxy.cc +++ b/content/browser/media/frameless_media_interface_proxy.cc @@ -151,6 +151,7 @@ void FramelessMediaInterfaceProxy::CreateMediaFoundationRenderer( void FramelessMediaInterfaceProxy::CreateCdm(const media::CdmConfig& cdm_config, CreateCdmCallback callback) { + LOG(INFO) << "[NEU][CDM]" << __func__; std::move(callback).Run(mojo::NullRemote(), nullptr, "CDM not supported"); } @@ -171,13 +172,14 @@ void FramelessMediaInterfaceProxy::ConnectToMediaService() { mojo::PendingRemote interfaces; std::ignore = interfaces.InitWithNewPipeAndPassReceiver(); - + LOG(INFO) << "[NEU][CDM]" << __func__; GetMediaService().CreateInterfaceFactory( interface_factory_remote_.BindNewPipeAndPassReceiver(), std::move(interfaces)); interface_factory_remote_.set_disconnect_handler(base::BindOnce( &FramelessMediaInterfaceProxy::OnMediaServiceConnectionError, base::Unretained(this))); + LOG(INFO) << "[NEU][CDM]" << __func__; } void FramelessMediaInterfaceProxy::OnMediaServiceConnectionError() { diff --git a/content/browser/media/key_system_support_impl.cc b/content/browser/media/key_system_support_impl.cc index 1b849706086871a5189c5d9811c5f1ae1f27d09a..99821d47ff140ca190bde4159ba135c09ae9c671 100644 --- a/content/browser/media/key_system_support_impl.cc +++ b/content/browser/media/key_system_support_impl.cc @@ -55,23 +55,27 @@ void KeySystemSupportImpl::Bind( void KeySystemSupportImpl::AddObserver( mojo::PendingRemote observer) { DVLOG(3) << __func__; - + LOG(INFO) << "[NEU][CDM]" << __func__; auto id = observer_remotes_.Add(std::move(observer)); // If `key_system_support_` is already available, notify the new observer // immediately. All observers will be notified if there are updates later. if (key_system_capabilities_.has_value()) { + LOG(INFO) << "[NEU][CDM]" << __func__; observer_remotes_.Get(id)->OnKeySystemSupportUpdated( CloneKeySystemCapabilities()); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } // Observe key system capabilities if not have done so. if (!is_observing_) ObserveKeySystemCapabilities(); + LOG(INFO) << "[NEU][CDM]" << __func__; } void KeySystemSupportImpl::ObserveKeySystemCapabilities() { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(!is_observing_); is_observing_ = true; @@ -87,10 +91,12 @@ void KeySystemSupportImpl::ObserveKeySystemCapabilities() { CdmRegistryImpl::GetInstance()->ObserveKeySystemCapabilities( std::move(result_cb)); + LOG(INFO) << "[NEU][CDM]" << __func__; } void KeySystemSupportImpl::OnKeySystemCapabilitiesUpdated( KeySystemCapabilities key_system_capabilities) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(3) << __func__; DCHECK(IsValidKeySystemCapabilities(key_system_capabilities)); @@ -101,9 +107,11 @@ void KeySystemSupportImpl::OnKeySystemCapabilitiesUpdated( } key_system_capabilities_ = std::move(key_system_capabilities); - - for (auto& observer : observer_remotes_) + for (auto& observer : observer_remotes_) { + LOG(INFO) << "[NEU][CDM]" << __func__; observer->OnKeySystemSupportUpdated(CloneKeySystemCapabilities()); + } + LOG(INFO) << "[NEU][CDM]" << __func__; } KeySystemCapabilityPtrMap KeySystemSupportImpl::CloneKeySystemCapabilities() { diff --git a/content/browser/media/key_system_support_ohos.cc b/content/browser/media/key_system_support_ohos.cc new file mode 100644 index 0000000000000000000000000000000000000000..83e34df885b1d85a06fcc45bab96e6e5bd642cd4 --- /dev/null +++ b/content/browser/media/key_system_support_ohos.cc @@ -0,0 +1,128 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/media/key_system_support_ohos.h" + +#include +#include + +#include "base/feature_list.h" +#include "media/base/audio_codecs.h" +#include "media/base/content_decryption_module.h" +#include "media/base/eme_constants.h" +#include "media/base/encryption_scheme.h" +#include "media/base/media_switches.h" +#include "media/base/media_util.h" +#include "media/base/ohos/ohos_media_codec_util.h" +#include "media/base/ohos/ohos_media_drm_bridge.h" +#include "media/base/video_codecs.h" + +using media::OHOSMediaCodecUtil; +using media::OHOSMediaDrmBridge; + +namespace content { +namespace { + +const media::AudioCodec kWebMAudioCodecsToQuery[] = { + media::AudioCodec::kOpus, +}; + +const media::AudioCodec kMP4AudioCodecsToQuery[] = { + media::AudioCodec::kFLAC, +#if BUILDFLAG(USE_PROPRIETARY_CODECS) + media::AudioCodec::kAAC, +#if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO) + media::AudioCodec::kAC3, media::AudioCodec::kEAC3, +#endif +#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO) + media::AudioCodec::kDTS, media::AudioCodec::kDTSXP2, +#endif +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) +}; + +const media::VideoCodec kWebMVideoCodecsToQuery[] = { + media::VideoCodec::kVP8, + media::VideoCodec::kVP9, +}; + +const media::VideoCodec kMP4VideoCodecsToQuery[] = { + media::VideoCodec::kVP9, +#if BUILDFLAG(USE_PROPRIETARY_CODECS) + media::VideoCodec::kH264, +#if BUILDFLAG(ENABLE_PLATFORM_HEVC) + media::VideoCodec::kHEVC, +#endif +#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) + media::VideoCodec::kDolbyVision, +#endif +#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) +}; +} // namespace + +void GetOHOSCdmCapability(const std::string& key_system, + CdmInfo::Robustness robustness, + media::CdmCapabilityCB cdm_capability_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; + const bool is_secure = robustness == CdmInfo::Robustness::kHardwareSecure; + if (!OHOSMediaDrmBridge::IsKeySystemSupported(key_system)) { + LOG(INFO) << "[NEU][CDM]" << __func__ << "Key system " << key_system + << " not supported."; + std::move(cdm_capability_cb).Run(absl::nullopt); + return; + } + + const std::vector kAllProfiles = {}; + media::CdmCapability capability; + if (OHOSMediaDrmBridge::IsKeySystemSupportedWithType(key_system, + "video/webm")) { + for (const auto& codec : kWebMAudioCodecsToQuery) { + if (OHOSMediaCodecUtil::CanDecode(codec)) { + capability.audio_codecs.insert(codec); + } + } + for (const auto& codec : kWebMVideoCodecsToQuery) { + if (OHOSMediaCodecUtil::CanDecode(codec, is_secure)) { + capability.video_codecs.emplace(codec, kAllProfiles); + } + } + } + + if (OHOSMediaDrmBridge::IsKeySystemSupportedWithType(key_system, + "video/mp4")) { + for (const auto& codec : kMP4AudioCodecsToQuery) { + if (!capability.audio_codecs.contains(codec)) { + if (OHOSMediaCodecUtil::CanDecode(codec)) { + capability.audio_codecs.insert(codec); + } + } + } + for (const auto& codec : kMP4VideoCodecsToQuery) { + if (!capability.video_codecs.contains(codec)) { + if (OHOSMediaCodecUtil::CanDecode(codec, is_secure)) { + capability.video_codecs.emplace(codec, kAllProfiles); + } + } + } + } + + if (is_secure && capability.video_codecs.empty()) { + LOG(INFO) << "Key system " << key_system + << " not supported as no hardware secure video codecs available."; + std::move(cdm_capability_cb).Run(absl::nullopt); + return; + } + + capability.encryption_schemes.insert(media::EncryptionScheme::kCenc); + capability.encryption_schemes.insert(media::EncryptionScheme::kCbcs); + + capability.session_types.insert(media::CdmSessionType::kTemporary); + if (OHOSMediaDrmBridge::IsPersistentLicenseTypeSupported(key_system)) { + capability.session_types.insert(media::CdmSessionType::kPersistentLicense); + } + + std::move(cdm_capability_cb).Run(capability); + LOG(INFO) << "[NEU][CDM]" << __func__; +} + +} // namespace content diff --git a/content/browser/media/key_system_support_ohos.h b/content/browser/media/key_system_support_ohos.h new file mode 100644 index 0000000000000000000000000000000000000000..4faebdd3a6561296bc389949ee60f97aa796d3b8 --- /dev/null +++ b/content/browser/media/key_system_support_ohos.h @@ -0,0 +1,23 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_MEDIA_KEY_SYSTEM_SUPPORT_OHOS_H_ +#define CONTENT_BROWSER_MEDIA_KEY_SYSTEM_SUPPORT_OHOS_H_ + +#include + +#include "base/functional/callback.h" +#include "content/public/common/cdm_info.h" +#include "media/cdm/cdm_capability.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace content { + +void GetOHOSCdmCapability(const std::string& key_system, + CdmInfo::Robustness robustness, + media::CdmCapabilityCB cdm_capability_cb); + +} // namespace content + +#endif // CONTENT_BROWSER_MEDIA_KEY_SYSTEM_SUPPORT_OHOS_H_ diff --git a/content/browser/media/media_interface_factory_holder.cc b/content/browser/media/media_interface_factory_holder.cc index e04289defc847f17cec95953f17e2ddc0bf7987a..dded697ea70971ecdae878a285e2361dab6ef7d6 100644 --- a/content/browser/media/media_interface_factory_holder.cc +++ b/content/browser/media/media_interface_factory_holder.cc @@ -26,12 +26,14 @@ media::mojom::InterfaceFactory* MediaInterfaceFactoryHolder::Get() { } void MediaInterfaceFactoryHolder::ConnectToMediaService() { + LOG(INFO) << "[NEU][CDM]" << __func__; media_service_getter_.Run().CreateInterfaceFactory( interface_factory_remote_.BindNewPipeAndPassReceiver(), frame_services_getter_.Run()); // Handle unexpected mojo pipe disconnection such as media service process // crashed or killed in the browser task manager. interface_factory_remote_.reset_on_disconnect(); + LOG(INFO) << "[NEU][CDM]" << __func__; } diff --git a/content/browser/media/media_interface_proxy.cc b/content/browser/media/media_interface_proxy.cc index 9c8b3b4d768dc70a4cb091779d882ef73dc5e15f..a8cec77dc0a63b69d8f670b14e4681d7497a2974 100644 --- a/content/browser/media/media_interface_proxy.cc +++ b/content/browser/media/media_interface_proxy.cc @@ -163,12 +163,15 @@ class FrameInterfaceFactoryImpl : public media::mojom::FrameInterfaceFactory, void CreateProvisionFetcher( mojo::PendingReceiver receiver) override { + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(ENABLE_MOJO_CDM) + LOG(INFO) << "[NEU][CDM]" << __func__; ProvisionFetcherImpl::Create(render_frame_host_->GetBrowserContext() ->GetDefaultStoragePartition() ->GetURLLoaderFactoryForBrowserProcess(), std::move(receiver)); #endif + LOG(INFO) << "[NEU][CDM]" << __func__; } void CreateCdmStorage( @@ -218,8 +221,10 @@ class FrameInterfaceFactoryImpl : public media::mojom::FrameInterfaceFactory, } void BindEmbedderReceiver(mojo::GenericPendingReceiver receiver) override { + LOG(INFO) << "[NEU][CDM]" << __func__; GetContentClient()->browser()->BindMediaServiceReceiver( render_frame_host_, std::move(receiver)); + LOG(INFO) << "[NEU][CDM]" << __func__; } #if BUILDFLAG(IS_WIN) @@ -431,6 +436,7 @@ void MediaInterfaceProxy::CreateMediaFoundationRenderer( void MediaInterfaceProxy::CreateCdm(const media::CdmConfig& cdm_config, CreateCdmCallback create_cdm_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(thread_checker_.CalledOnValidThread()); DVLOG(1) << __func__ << ": cdm_config=" << cdm_config; @@ -440,26 +446,33 @@ void MediaInterfaceProxy::CreateCdm(const media::CdmConfig& cdm_config, auto callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun( std::move(create_cdm_cb), mojo::NullRemote(), nullptr, "CDM creation failed"); - + LOG(INFO) << "[NEU][CDM]" << __func__; // Handle `use_hw_secure_codecs` cases first. #if BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA) + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(IS_CHROMEOS_LACROS) + LOG(INFO) << "[NEU][CDM]" << __func__; const bool enable_cdm_factory_daemon = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kLacrosUseChromeosProtectedMedia); #else // BUILDFLAG(IS_CHROMEOS_LACROS) + LOG(INFO) << "[NEU][CDM]" << __func__; const bool enable_cdm_factory_daemon = true; #endif // else BUILDFLAG(IS_CHROMEOS_LACROS) + LOG(INFO) << "[NEU][CDM]" << __func__; if (enable_cdm_factory_daemon && cdm_config.use_hw_secure_codecs && cdm_config.allow_distinctive_identifier) { auto* factory = media_interface_factory_ptr_->Get(); + LOG(INFO) << "[NEU][CDM]" << __func__; if (factory) { // We need to intercept the callback in this case so we can fallback to // the library CDM in case of failure. + LOG(INFO) << "[NEU][CDM]" << __func__; factory->CreateCdm( cdm_config, base::BindOnce(&MediaInterfaceProxy::OnChromeOsCdmCreated, weak_factory_.GetWeakPtr(), cdm_config, std::move(callback))); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } } @@ -491,25 +504,30 @@ void MediaInterfaceProxy::CreateCdm(const media::CdmConfig& cdm_config, #if BUILDFLAG(ENABLE_LIBRARY_CDMS) // Fallback to use CdmFactory even if `use_hw_secure_codecs` is true. + LOG(INFO) << "[NEU][CDM]" << __func__; auto* factory = GetCdmFactory(cdm_config.key_system); #elif BUILDFLAG(ENABLE_CAST_RENDERER) // CDM service lives together with renderer service if cast renderer is // enabled, because cast renderer creates its own audio/video decoder. Note // that in content_browsertests (and Content Shell in general) we don't have // an a cast renderer and this interface will be unbound. + LOG(INFO) << "[NEU][CDM]" << __func__; auto* factory = secondary_interface_factory_->Get(); #else // CDM service lives together with audio/video decoder service. + LOG(INFO) << "[NEU][CDM]" << __func__; auto* factory = media_interface_factory_ptr_->Get(); #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) - + LOG(INFO) << "[NEU][CDM]" << __func__; if (!factory) { + LOG(INFO) << "[NEU][CDM]" << __func__; std::move(callback).Run(mojo::NullRemote(), nullptr, "Unable to find a CDM factory"); return; } - + LOG(INFO) << "[NEU][CDM]" << __func__; factory->CreateCdm(cdm_config, std::move(callback)); + LOG(INFO) << "[NEU][CDM]" << __func__; } mojo::PendingRemote diff --git a/content/browser/media/media_service.cc b/content/browser/media/media_service.cc index b3fd445709f274c752254539cb17f02bea0123a7..6862604268512414c58db0e9629a1d2ebadc2835 100644 --- a/content/browser/media/media_service.cc +++ b/content/browser/media/media_service.cc @@ -27,30 +27,37 @@ media::mojom::MediaService& GetMediaService() { // that of the UI-thread sequence. This ensures that the Remote is destroyed // when the task environment is torn down and reinitialized, e.g. between unit // tests. + LOG(INFO) << "[NEU][CDM]" << __func__; static base::SequenceLocalStorageSlot< mojo::Remote> remote_slot; auto& remote = remote_slot.GetOrCreateValue(); + LOG(INFO) << "[NEU][CDM]" << __func__; if (!remote) { auto receiver = remote.BindNewPipeAndPassReceiver(); remote.reset_on_disconnect(); - + LOG(INFO) << "[NEU][CDM]----" << __func__; #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) auto* process_host = GpuProcessHost::Get(); + LOG(INFO) << "[NEU][CDM]-----" << __func__; if (process_host) { process_host->RunService(std::move(receiver)); + LOG(INFO) << "[NEU][CDM]-----" << __func__; } else { + LOG(INFO) << "[NEU][CDM]-----" << __func__; DLOG(ERROR) << "GPU process host not available"; } #elif BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS) + LOG(INFO) << "[NEU][CDM]" << __func__; static_assert(media::mojom::MediaService::kServiceSandbox == sandbox::mojom::Sandbox::kNoSandbox, "MediaService requested in-browser but not with kNoSandbox"); static base::NoDestructor> service; *service = media::CreateMediaService(std::move(receiver)); + LOG(INFO) << "[NEU][CDM]-----" << __func__; #endif } - + LOG(INFO) << "[NEU][CDM]" << __func__; return *remote.get(); } diff --git a/content/browser/media/url_provision_fetcher.cc b/content/browser/media/url_provision_fetcher.cc index e3c6fd24803054f2715546f51244622fa8ed7335..d64dfd7915ae2a2f38e5b64cb514345bc67ffeac 100644 --- a/content/browser/media/url_provision_fetcher.cc +++ b/content/browser/media/url_provision_fetcher.cc @@ -121,6 +121,7 @@ void URLProvisionFetcher::OnSimpleLoaderComplete( std::unique_ptr CreateProvisionFetcher( scoped_refptr url_loader_factory) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(url_loader_factory); return std::make_unique(std::move(url_loader_factory)); } diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc index 3712776584817432ed1d340640f6bbdd3d777849..55956f948397b5446066c9c49a4a86b347970a88 100644 --- a/content/gpu/gpu_child_thread.cc +++ b/content/gpu/gpu_child_thread.cc @@ -52,6 +52,10 @@ #include "media/mojo/clients/mojo_android_overlay.h" #endif +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +#include "media/base/ohos/ohos_media_drm_bridge_client.h" +#endif + #if BUILDFLAG(IS_CHROMEOS_ASH) #include "components/services/font/public/cpp/font_loader.h" // nogncheck #include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck @@ -148,6 +152,13 @@ void GpuChildThread::Init(const base::TimeTicks& process_start_time) { } #endif +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + if (!in_process_gpu()) { + media::SetMediaDrmBridgeClient( + GetContentClient()->GetMediaDrmBridgeClient()); + } +#endif + #if BUILDFLAG(IS_CHROMEOS_ASH) if (!in_process_gpu()) { mojo::PendingRemote font_service; diff --git a/content/gpu/gpu_child_thread_receiver_bindings.cc b/content/gpu/gpu_child_thread_receiver_bindings.cc index 00c2a6a4dfe7e7d173fe3651e30ec2e9865ba35e..7d6b9240ef880dc4692f162478284ae286043f11 100644 --- a/content/gpu/gpu_child_thread_receiver_bindings.cc +++ b/content/gpu/gpu_child_thread_receiver_bindings.cc @@ -55,7 +55,9 @@ void GpuChildThread::BindServiceInterface( #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) if (auto r = receiver.As()) { + LOG(INFO) << "[NEU][CDM]" << __func__; service_factory_->RunMediaService(std::move(r)); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } #endif diff --git a/content/gpu/gpu_service_factory.cc b/content/gpu/gpu_service_factory.cc index 8470a0620b21dae031a351e3e20c71958565b634..e9b59d35a005f8bba70b8c0a74bf7797b8524b8b 100644 --- a/content/gpu/gpu_service_factory.cc +++ b/content/gpu/gpu_service_factory.cc @@ -52,6 +52,7 @@ GpuServiceFactory::~GpuServiceFactory() {} void GpuServiceFactory::RunMediaService( mojo::PendingReceiver receiver) { + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) // This service will host audio/video decoders, and if these decoding // operations are blocked, user may hear audio glitch or see video @@ -83,11 +84,13 @@ void GpuServiceFactory::RunMediaService( using FactoryCallback = base::OnceCallback()>; + LOG(INFO) << "[NEU][CDM]" << __func__; FactoryCallback factory = base::BindOnce(&media::CreateGpuMediaService, std::move(receiver), gpu_preferences_, gpu_workarounds_, gpu_feature_info_, gpu_info_, task_runner_, media_gpu_channel_manager_, gpu_memory_buffer_factory_, android_overlay_factory_cb_); + LOG(INFO) << "[NEU][CDM]" << __func__; task_runner->PostTask( FROM_HERE, base::BindOnce( diff --git a/content/public/common/content_client.cc b/content/public/common/content_client.cc index 852b9c6f971ae24545c8d31a66e6663f3b23ed3f..f229696484bd38c154fb09a463476394719dd327 100644 --- a/content/public/common/content_client.cc +++ b/content/public/common/content_client.cc @@ -147,6 +147,12 @@ media::MediaDrmBridgeClient* ContentClient::GetMediaDrmBridgeClient() { } #endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +media::OHOSMediaDrmBridgeClient* ContentClient::GetMediaDrmBridgeClient() { + return nullptr; +} +#endif // BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + void ContentClient::ExposeInterfacesToBrowser( scoped_refptr io_task_runner, mojo::BinderMap* binders) {} diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h index c2033ce9c84d7a3e703bebdabf98dfcb9198ea9d..a970b9c3d5c9557e672cba635ac677669c8f629a 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h @@ -40,6 +40,9 @@ struct GPUInfo; namespace media { struct CdmHostFilePath; class MediaDrmBridgeClient; +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +class OHOSMediaDrmBridgeClient; +#endif // BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) } namespace mojo { @@ -198,6 +201,10 @@ class CONTENT_EXPORT ContentClient { virtual media::MediaDrmBridgeClient* GetMediaDrmBridgeClient(); #endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + virtual media::OHOSMediaDrmBridgeClient* GetMediaDrmBridgeClient(); +#endif // BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + // Allows the embedder to handle incoming interface binding requests from // the browser process to any type of child process. This is called once // in each child process during that process's initialization. diff --git a/content/public/renderer/content_renderer_client.cc b/content/public/renderer/content_renderer_client.cc index b8f771e9ced5047d3f2fcaf797db8a1426f039ef..072c8e9c2a96eb96948ec6681655cc761189cbd3 100644 --- a/content/public/renderer/content_renderer_client.cc +++ b/content/public/renderer/content_renderer_client.cc @@ -160,6 +160,7 @@ bool ContentRendererClient::IsOriginIsolatedPepperPlugin( void ContentRendererClient::GetSupportedKeySystems( media::GetSupportedKeySystemsCB cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; std::move(cb).Run({}); } diff --git a/content/public/renderer/key_system_support.cc b/content/public/renderer/key_system_support.cc index d9fafe7a41600d9a30dc0fac7236d37362a57c23..bff6491b4c223d8bd7319288a97adec0fcddaefa 100644 --- a/content/public/renderer/key_system_support.cc +++ b/content/public/renderer/key_system_support.cc @@ -26,7 +26,9 @@ class KeySystemSupportObserverImpl // media::mojom::KeySystemSupportObserver void OnKeySystemSupportUpdated( KeySystemCapabilityPtrMap key_system_capabilities) final { + LOG(INFO) << "[NEU][CDM]" << __func__; key_system_support_cb_.Run(std::move(key_system_capabilities)); + LOG(INFO) << "[NEU][CDM]" << __func__; } private: @@ -36,6 +38,7 @@ class KeySystemSupportObserverImpl } // namespace void ObserveKeySystemSupportUpdate(KeySystemSupportCB cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; // `key_system_support` will be destructed after this function returns. This @@ -50,6 +53,7 @@ void ObserveKeySystemSupportUpdate(KeySystemSupportCB cb) { std::make_unique(std::move(cb)), observer_remote.InitWithNewPipeAndPassReceiver()); key_system_support->AddObserver(std::move(observer_remote)); + LOG(INFO) << "[NEU][CDM]" << __func__; } } // namespace content diff --git a/content/renderer/media/cast_renderer_factory.cc b/content/renderer/media/cast_renderer_factory.cc index a723e1aaa9d01cbba6e3f2e702ace4c765e1684a..88cbabdd80ba56877cbb89743e2d119b8fdcb96c 100644 --- a/content/renderer/media/cast_renderer_factory.cc +++ b/content/renderer/media/cast_renderer_factory.cc @@ -55,7 +55,7 @@ std::unique_ptr CastRendererFactory::CreateRenderer( gmb_pool = std::make_unique( media_task_runner, std::move(worker_task_runner), gpu_factories); } - + LOG(INFO) << "[NEU][CDM]" << __func__; auto video_renderer = std::make_unique( media_task_runner, video_renderer_sink, // Unretained is safe here, because the RendererFactory is guaranteed to diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index 320374eb5732b3fbfbc41aca69ad45e6a3a369b2..9e87fa7c75665a6a76de3b29315a50e5912cb4ec 100755 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc @@ -941,20 +941,23 @@ media::mojom::RemoterFactory* MediaFactory::GetRemoterFactory() { #endif media::CdmFactory* MediaFactory::GetCdmFactory() { + LOG(INFO) << "[NEU][CDM]" << __func__; if (cdm_factory_) return cdm_factory_.get(); - + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(IS_FUCHSIA) DCHECK(interface_broker_); cdm_factory_ = std::make_unique( std::make_unique(interface_broker_)); #elif BUILDFLAG(ENABLE_MOJO_CDM) + LOG(INFO) << "[NEU][CDM]" << __func__; cdm_factory_ = std::make_unique(GetMediaInterfaceFactory()); #else + LOG(INFO) << "[NEU][CDM]" << __func__; cdm_factory_ = std::make_unique(); #endif // BUILDFLAG(ENABLE_MOJO_CDM) - + LOG(INFO) << "[NEU][CDM]" << __func__; return cdm_factory_.get(); } diff --git a/content/renderer/media/media_interface_factory.cc b/content/renderer/media/media_interface_factory.cc index 9bdaffc80606007c0f7c0c166b41d329549e2ec5..507f6200c3fee5c7f0cc3729516de5a76febcb42 100644 --- a/content/renderer/media/media_interface_factory.cc +++ b/content/renderer/media/media_interface_factory.cc @@ -219,6 +219,7 @@ void MediaInterfaceFactory::CreateMediaFoundationRenderer( void MediaInterfaceFactory::CreateCdm(const media::CdmConfig& cdm_config, CreateCdmCallback callback) { + LOG(INFO) << "[NEU][CDM]" << __func__; if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( FROM_HERE, base::BindOnce(&MediaInterfaceFactory::CreateCdm, weak_this_, @@ -228,10 +229,12 @@ void MediaInterfaceFactory::CreateCdm(const media::CdmConfig& cdm_config, DVLOG(1) << __func__ << ": cdm_config=" << cdm_config; GetMediaInterfaceFactory()->CreateCdm(cdm_config, std::move(callback)); + LOG(INFO) << "[NEU][CDM]" << __func__; } media::mojom::InterfaceFactory* MediaInterfaceFactory::GetMediaInterfaceFactory() { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); @@ -241,7 +244,7 @@ MediaInterfaceFactory::GetMediaInterfaceFactory() { media_interface_factory_.set_disconnect_handler(base::BindOnce( &MediaInterfaceFactory::OnConnectionError, base::Unretained(this))); } - + LOG(INFO) << "[NEU][CDM]" << __func__; return media_interface_factory_.get(); } diff --git a/content/renderer/media/media_permission_dispatcher.cc b/content/renderer/media/media_permission_dispatcher.cc index 5bf380abf4771b758af86737669df2616752296e..3aecaf37e99f1ea05df063edb303d0b174c4b7ab 100644 --- a/content/renderer/media/media_permission_dispatcher.cc +++ b/content/renderer/media/media_permission_dispatcher.cc @@ -89,6 +89,7 @@ void MediaPermissionDispatcher::HasPermission( void MediaPermissionDispatcher::RequestPermission( Type type, PermissionStatusCB permission_status_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; if (!task_runner_->RunsTasksInCurrentSequence()) { task_runner_->PostTask( FROM_HERE, base::BindOnce(&MediaPermissionDispatcher::RequestPermission, diff --git a/content/renderer/media/render_media_client.cc b/content/renderer/media/render_media_client.cc index bb227578a976b7dc4db0af1eca89e881b7537c44..ae74ba9780262d98d2751b4491997da2d9e8b587 100644 --- a/content/renderer/media/render_media_client.cc +++ b/content/renderer/media/render_media_client.cc @@ -78,7 +78,9 @@ RenderMediaClient::~RenderMediaClient() = default; void RenderMediaClient::GetSupportedKeySystems( media::GetSupportedKeySystemsCB cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; GetContentClient()->renderer()->GetSupportedKeySystems(std::move(cb)); + LOG(INFO) << "[NEU][CDM]" << __func__; } bool RenderMediaClient::IsSupportedAudioType(const media::AudioType& type) { diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 6fba6c48a825e67ac8e7312281a5710a27eab813..e624c94e1f322bbc39d67b01a4a7ee10132b3f83 100755 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -3293,6 +3293,7 @@ blink::WebMediaPlayer* RenderFrameImpl::CreateMediaPlayer( // `settings` should be non-null since the WebView created for // RenderFrameImpl always composites. DCHECK(settings); + LOG(INFO) << "[NEU][CDM]" << __func__; return media_factory_.CreateMediaPlayer( source, client, inspector_context, encrypted_client, initial_cdm, sink_id, GetLocalRootWebFrameWidget()->GetFrameSinkId(), *settings, @@ -4535,6 +4536,7 @@ RenderFrameImpl::MediaStreamDeviceObserver() { } blink::WebEncryptedMediaClient* RenderFrameImpl::EncryptedMediaClient() { + LOG(INFO) << "[NEU][CDM]" << __func__; return media_factory_.EncryptedMediaClient(); } diff --git a/content/shell/renderer/shell_content_renderer_client.cc b/content/shell/renderer/shell_content_renderer_client.cc index 0ffa369c1668d7170d714894e53aa24c1ee7b565..77a367ef12051ac46284bca45f1c596a65cc5e67 100644 --- a/content/shell/renderer/shell_content_renderer_client.cc +++ b/content/shell/renderer/shell_content_renderer_client.cc @@ -269,11 +269,13 @@ ShellContentRendererClient::CreateURLLoaderThrottleProvider( #if BUILDFLAG(ENABLE_MOJO_CDM) void ShellContentRendererClient::GetSupportedKeySystems( media::GetSupportedKeySystemsCB cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; media::KeySystemInfos key_systems; if (base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting)) key_systems.push_back( std::make_unique()); std::move(cb).Run(std::move(key_systems)); + LOG(INFO) << "[NEU][CDM]" << __func__; } #endif diff --git a/media/base/cdm_context.cc b/media/base/cdm_context.cc index 50d95a78575baa52355691f605d4502e7e40d7f1..00516549917e56291a6a039f6d33994d53236f96 100644 --- a/media/base/cdm_context.cc +++ b/media/base/cdm_context.cc @@ -47,6 +47,12 @@ MediaCryptoContext* CdmContext::GetMediaCryptoContext() { } #endif +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +OHOSMediaCryptoContext* CdmContext::GetOHOSMediaCryptoContext() { + return nullptr; +} +#endif + #if BUILDFLAG(IS_FUCHSIA) FuchsiaCdmContext* CdmContext::GetFuchsiaCdmContext() { return nullptr; diff --git a/media/base/cdm_context.h b/media/base/cdm_context.h index 260251b42fc6911d383c931b04b991a6598b45b8..51572d3e5fb3d9b56b06631c99cc86d00525b2af 100644 --- a/media/base/cdm_context.h +++ b/media/base/cdm_context.h @@ -28,6 +28,9 @@ namespace media { class CallbackRegistration; class Decryptor; class MediaCryptoContext; +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +class OHOSMediaCryptoContext; +#endif #if BUILDFLAG(IS_FUCHSIA) class FuchsiaCdmContext; @@ -112,6 +115,10 @@ class MEDIA_EXPORT CdmContext { virtual MediaCryptoContext* GetMediaCryptoContext(); #endif +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) + virtual OHOSMediaCryptoContext* GetOHOSMediaCryptoContext(); +#endif + #if BUILDFLAG(IS_FUCHSIA) // Returns FuchsiaCdmContext interface when the context is backed by Fuchsia // CDM. Otherwise returns nullptr. diff --git a/media/base/key_system_info.cc b/media/base/key_system_info.cc index b8add8a57831d449ee9e82cfcd013ff279e24e67..0e9bd2158644d66acab30660896101cbeab38bf3 100644 --- a/media/base/key_system_info.cc +++ b/media/base/key_system_info.cc @@ -3,11 +3,13 @@ // found in the LICENSE file. #include "media/base/key_system_info.h" +#include "base/logging.h" namespace media { bool KeySystemInfo::IsSupportedKeySystem(const std::string& key_system) const { // By default, only support the base key system. + LOG(INFO) << "[NEU][CDM]" << __func__; return key_system == GetBaseKeySystemName(); } diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc index d43a6b4017ad688426c731e32e9fe7b72ebf51c3..a07b519d857e32d0bfbb37d40a3d034338f45545 100644 --- a/media/base/key_systems.cc +++ b/media/base/key_systems.cc @@ -150,6 +150,7 @@ class ClearKeyKeySystemInfo : public KeySystemInfo { std::string GetBaseKeySystemName() const final { return kClearKeyKeySystem; } bool IsSupportedInitDataType(EmeInitDataType init_data_type) const final { + LOG(INFO) << "[NEU][CDM]" << __func__; return init_data_type == EmeInitDataType::CENC || init_data_type == EmeInitDataType::WEBM || init_data_type == EmeInitDataType::KEYIDS; @@ -157,6 +158,7 @@ class ClearKeyKeySystemInfo : public KeySystemInfo { EmeConfig::Rule GetEncryptionSchemeConfigRule( EncryptionScheme encryption_scheme) const final { + LOG(INFO) << "[NEU][CDM]" << __func__; switch (encryption_scheme) { case EncryptionScheme::kCenc: case EncryptionScheme::kCbcs: { @@ -170,6 +172,7 @@ class ClearKeyKeySystemInfo : public KeySystemInfo { } SupportedCodecs GetSupportedCodecs() const final { + LOG(INFO) << "[NEU][CDM]" << __func__; // On Android, Vorbis, VP8, AAC and AVC1 are supported in MediaCodec: // http://developer.android.com/guide/appendix/media-formats.html // VP9 support is device dependent. @@ -181,26 +184,35 @@ class ClearKeyKeySystemInfo : public KeySystemInfo { EmeMediaType media_type, const std::string& requested_robustness, const bool* /*hw_secure_requirement*/) const final { + LOG(INFO) << "[NEU][CDM]" << __func__; if (requested_robustness.empty()) { + LOG(INFO) << "[NEU][CDM]" << __func__; return EmeConfig::SupportedRule(); } else { + LOG(INFO) << "[NEU][CDM]" << __func__; return EmeConfig::UnsupportedRule(); } } EmeConfig::Rule GetPersistentLicenseSessionSupport() const final { + LOG(INFO) << "[NEU][CDM]" << __func__; return EmeConfig::UnsupportedRule(); } EmeFeatureSupport GetPersistentStateSupport() const final { + LOG(INFO) << "[NEU][CDM]" << __func__; return EmeFeatureSupport::NOT_SUPPORTED; } EmeFeatureSupport GetDistinctiveIdentifierSupport() const final { + LOG(INFO) << "[NEU][CDM]" << __func__; return EmeFeatureSupport::NOT_SUPPORTED; } - bool UseAesDecryptor() const final { return true; } + bool UseAesDecryptor() const final { + LOG(INFO) << "[NEU][CDM]" << __func__; + return true; + } }; // Returns whether the |key_system| is known to Chromium and is thus likely to @@ -397,16 +409,18 @@ KeySystemsImpl::~KeySystemsImpl() { } void KeySystemsImpl::Initialize() { + LOG(INFO) << "[NEU][DRM]Initialize Start."; for (const auto& [mime_type, codecs] : kMimeTypeToCodecsMap) RegisterMimeType(mime_type, codecs); UpdateSupportedKeySystems(); + LOG(INFO) << "[NEU][DRM]Initialize End."; } void KeySystemsImpl::UpdateSupportedKeySystems() { DCHECK(!is_updating_); is_updating_ = true; - + LOG(INFO) << "[NEU][DRM]UpdateSupportedKeySystems Start."; if (!GetMediaClient()) { OnSupportedKeySystemsUpdated({}); return; @@ -415,15 +429,17 @@ void KeySystemsImpl::UpdateSupportedKeySystems() { GetMediaClient()->GetSupportedKeySystems( base::BindRepeating(&KeySystemsImpl::OnSupportedKeySystemsUpdated, weak_factory_.GetWeakPtr())); + LOG(INFO) << "[NEU][DRM]UpdateSupportedKeySystems End."; } void KeySystemsImpl::UpdateIfNeeded(base::OnceClosure done_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; if (is_updating_) { // The callback will be resolved in OnSupportedKeySystemsUpdated(). update_callbacks_.AddUnsafe(std::move(done_cb)); return; } - + LOG(INFO) << "[NEU][CDM]" << __func__; std::move(done_cb).Run(); } @@ -482,25 +498,28 @@ EmeCodec KeySystemsImpl::GetEmeCodecForString( } void KeySystemsImpl::OnSupportedKeySystemsUpdated(KeySystemInfos key_systems) { + LOG(INFO) << "[NEU][DRM]OnSupportedKeySystemsUpdated Start."; DVLOG(1) << __func__; is_updating_ = false; - + LOG(INFO) << "[NEU][DRM]OnSupportedKeySystemsUpdated 111."; // Clear Key is always supported. key_systems.emplace_back(std::make_unique()); - + LOG(INFO) << "[NEU][DRM]OnSupportedKeySystemsUpdated 222."; ProcessSupportedKeySystems(std::move(key_systems)); - + LOG(INFO) << "[NEU][DRM]OnSupportedKeySystemsUpdated 333."; update_callbacks_.Notify(); + LOG(INFO) << "[NEU][DRM]OnSupportedKeySystemsUpdated End."; } void KeySystemsImpl::ProcessSupportedKeySystems(KeySystemInfos key_systems) { DCHECK(thread_checker_.CalledOnValidThread()); - + LOG(INFO) << "[NEU][DRM]ProcessSupportedKeySystems Start."; // Clear `key_system_info_vector_` before repopulating it. key_system_info_vector_.clear(); for (auto& key_system : key_systems) { + LOG(INFO) << "[NEU][DRM]ProcessSupportedKeySystems name: " << key_system->GetBaseKeySystemName().c_str(); DCHECK(!key_system->GetBaseKeySystemName().empty()); DCHECK(key_system->GetPersistentStateSupport() != EmeFeatureSupport::INVALID); @@ -511,6 +530,7 @@ void KeySystemsImpl::ProcessSupportedKeySystems(KeySystemInfos key_systems) { // If you encounter this path, see the comments for the function above. DLOG(ERROR) << "Unsupported name '" << key_system->GetBaseKeySystemName() << "'. See code comments."; + LOG(INFO) << "[NEU][DRM]ProcessSupportedKeySystems continue."; continue; } @@ -530,14 +550,19 @@ void KeySystemsImpl::ProcessSupportedKeySystems(KeySystemInfos key_systems) { const auto base_key_system_name = key_system->GetBaseKeySystemName(); DVLOG(1) << __func__ << ": Adding key system " << base_key_system_name; + LOG(INFO) << "[NEU][DRM]ProcessSupportedKeySystems push_back." << base_key_system_name; key_system_info_vector_.push_back(std::move(key_system)); + LOG(INFO) << "[NEU][DRM]ProcessSupportedKeySystems push_back."; } + LOG(INFO) << "[NEU][DRM]ProcessSupportedKeySystems End."; } const KeySystemInfo* KeySystemsImpl::GetKeySystemInfo( const std::string& key_system) const { DCHECK(!is_updating_); + LOG(INFO) << "[NEU][CDM]" << __func__; for (const auto& key_system_info : key_system_info_vector_) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", " << key_system_info->GetBaseKeySystemName(); const auto& base_key_system = key_system_info->GetBaseKeySystemName(); if ((key_system == base_key_system || IsSubKeySystemOf(key_system, base_key_system)) && @@ -545,7 +570,7 @@ const KeySystemInfo* KeySystemsImpl::GetKeySystemInfo( return key_system_info.get(); } } - + LOG(INFO) << "[NEU][CDM]" << __func__ << " NULL."; return nullptr; } @@ -582,6 +607,7 @@ bool KeySystemsImpl::IsValidMimeTypeCodecsCombination( bool KeySystemsImpl::IsSupportedInitDataType( const std::string& key_system, EmeInitDataType init_data_type) const { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(thread_checker_.CalledOnValidThread()); const auto* key_system_info = GetKeySystemInfo(key_system); @@ -589,7 +615,7 @@ bool KeySystemsImpl::IsSupportedInitDataType( NOTREACHED(); return false; } - + LOG(INFO) << "[NEU][CDM]" << __func__; return key_system_info->IsSupportedInitDataType(init_data_type); } @@ -655,7 +681,7 @@ std::string KeySystemsImpl::GetBaseKeySystemName( bool KeySystemsImpl::IsSupportedKeySystem(const std::string& key_system) const { DCHECK(thread_checker_.CalledOnValidThread()); - + LOG(INFO) << "[NEU][CDM]" << __func__; return GetKeySystemInfo(key_system); } @@ -673,6 +699,7 @@ bool KeySystemsImpl::ShouldUseBaseKeySystemName( } bool KeySystemsImpl::CanUseAesDecryptor(const std::string& key_system) const { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(thread_checker_.CalledOnValidThread()); const auto* key_system_info = GetKeySystemInfo(key_system); @@ -680,7 +707,7 @@ bool KeySystemsImpl::CanUseAesDecryptor(const std::string& key_system) const { DLOG(ERROR) << key_system << " is not a known supported key system"; return false; } - + LOG(INFO) << "[NEU][CDM]" << __func__; return key_system_info->UseAesDecryptor(); } @@ -840,6 +867,7 @@ EmeFeatureSupport KeySystemsImpl::GetDistinctiveIdentifierSupport( } // namespace KeySystems* KeySystems::GetInstance() { + LOG(INFO) << "[NEU][CDM]" << __func__; return KeySystemsImpl::GetInstance(); } diff --git a/media/base/ohos/BUILD.gn b/media/base/ohos/BUILD.gn index 72f6ec86b7844f34536eac7097bb8ceebd544443..2202e01ad8811cc520d88d1e19cae8078f23d933 100644 --- a/media/base/ohos/BUILD.gn +++ b/media/base/ohos/BUILD.gn @@ -4,6 +4,8 @@ if (is_ohos) { import("//build/config/ohos/config.gni") + ## import("//third_party/widevine/cdm/widevine.gni") + source_set("ohos") { visibility = [ "//media", @@ -33,6 +35,27 @@ if (is_ohos) { "decoder_format_adapter_impl.cc", "decoder_format_adapter_impl.h", ] + + if (defined(ohos_enable_cdm) && ohos_enable_cdm) { + sources += [ + "ohos_cdm_factory.cc", + "ohos_cdm_factory.h", + "ohos_media_crypto_context_impl.cc", + "ohos_media_crypto_context_impl.h", + "ohos_media_crypto_context.h", + "ohos_media_drm_bridge_client.cc", + "ohos_media_drm_bridge_client.h", + "ohos_media_drm_bridge_delegate.cc", + "ohos_media_drm_bridge_delegate.h", + "ohos_media_drm_bridge_factory.cc", + "ohos_media_drm_bridge_factory.h", + "ohos_media_drm_bridge.cc", + "ohos_media_drm_bridge.h", + "ohos_media_drm_storage_bridge.cc", + "ohos_media_drm_storage_bridge.h", + ] + } + configs += [ "//media:subcomponent_config" ] if (product_name == "rk3568") { @@ -42,6 +65,7 @@ if (is_ohos) { deps = [ "//media/base", "//url", + ##"//third_party/widevine/cdm:buildflags", ] include_dirs = ohos_src_includes diff --git a/media/base/ohos/ohos_cdm_factory.cc b/media/base/ohos/ohos_cdm_factory.cc new file mode 100644 index 0000000000000000000000000000000000000000..0967f1e610d38bf81f9bcd4070144874c6e2ff11 --- /dev/null +++ b/media/base/ohos/ohos_cdm_factory.cc @@ -0,0 +1,113 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/ohos/ohos_cdm_factory.h" + +#include "base/feature_list.h" +#include "base/functional/bind.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/strings/string_number_conversions.h" +#include "base/task/bind_post_task.h" +#include "media/base/cdm_config.h" +#include "media/base/content_decryption_module.h" +#include "media/base/key_system_names.h" +#include "media/base/media_switches.h" +#include "media/base/ohos/ohos_media_drm_bridge.h" +#include "media/cdm/aes_decryptor.h" +#include "url/origin.h" + +namespace media { + +namespace { + +void ReportMediaDrmBridgeKeySystemSupport(bool supported) { + UMA_HISTOGRAM_BOOLEAN("Media.EME.OHOSMediaDrmBridge.KeySystemSupport", + supported); +} + +} // namespace + +OHOSCdmFactory::OHOSCdmFactory(CreateFetcherCB create_fetcher_cb, + CreateStorageCB create_storage_cb) + : create_fetcher_cb_(std::move(create_fetcher_cb)), + create_storage_cb_(std::move(create_storage_cb)) {} + +OHOSCdmFactory::~OHOSCdmFactory() { + weak_factory_.InvalidateWeakPtrs(); + for (auto& pending_creation : pending_creations_) { + CdmCreatedCB cdm_created_cb = std::move(pending_creation.second.second); + std::move(cdm_created_cb).Run(nullptr, "CDM creation aborted"); + } +} + +void OHOSCdmFactory::Create( + const CdmConfig& cdm_config, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb, + CdmCreatedCB cdm_created_cb) { + DVLOG(1) << __func__; + LOG(INFO) << "[NEU][CDM]" << __func__; + // Bound |cdm_created_cb| so we always fire it asynchronously. + CdmCreatedCB bound_cdm_created_cb = + base::BindPostTaskToCurrentDefault(std::move(cdm_created_cb)); + + if (base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting) && + IsExternalClearKey(cdm_config.key_system)) { + scoped_refptr cdm( + new AesDecryptor(session_message_cb, session_closed_cb, + session_keys_change_cb, session_expiration_update_cb)); + std::move(bound_cdm_created_cb).Run(cdm, ""); + LOG(INFO) << "[NEU][CDM]" << __func__; + return; + } + + if (!OHOSMediaDrmBridge::IsKeySystemSupported(cdm_config.key_system)) { + ReportMediaDrmBridgeKeySystemSupport(false); + std::move(bound_cdm_created_cb) + .Run(nullptr, + "Key system not supported unexpectedly: " + cdm_config.key_system); + LOG(INFO) << "[NEU][CDM]" << __func__; + return; + } + + ReportMediaDrmBridgeKeySystemSupport(true); + + auto factory = std::make_unique( + create_fetcher_cb_, create_storage_cb_); + auto* raw_factory = factory.get(); + + creation_id_++; + auto result = pending_creations_.emplace( + creation_id_, + PendingCreation(std::move(factory), std::move(bound_cdm_created_cb))); + CHECK(result.second); + LOG(INFO) << "[NEU][CDM]" << __func__; + raw_factory->Create(cdm_config, session_message_cb, session_closed_cb, + session_keys_change_cb, session_expiration_update_cb, + base::BindOnce(&OHOSCdmFactory::OnCdmCreated, + weak_factory_.GetWeakPtr(), creation_id_)); + LOG(INFO) << "[NEU][CDM]" << __func__; +} + +void OHOSCdmFactory::OnCdmCreated( + uint32_t creation_id, + const scoped_refptr& cdm, + const std::string& error_message) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", " << error_message; + DVLOG(1) << __func__ << ": creation_id = " << creation_id; + LOG(INFO) << "[NEU][CDM]" << __func__ << ": creation_id = " << creation_id; + DCHECK(pending_creations_.contains(creation_id)); + CdmCreatedCB cdm_created_cb = + std::move(pending_creations_[creation_id].second); + pending_creations_.erase(creation_id); + + LOG_IF(ERROR, !cdm) << error_message; + std::move(cdm_created_cb).Run(cdm, error_message); + LOG(INFO) << "[NEU][CDM]" << __func__; +} + +} // namespace media diff --git a/media/base/ohos/ohos_cdm_factory.h b/media/base/ohos/ohos_cdm_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..4a6fae5df82e234d7d0c8fc5dfee2ff12e012d53 --- /dev/null +++ b/media/base/ohos/ohos_cdm_factory.h @@ -0,0 +1,62 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_OHOS_OHOS_CDM_FACTORY_H_ +#define MEDIA_BASE_OHOS_OHOS_CDM_FACTORY_H_ + +#include + +#include + +#include "base/containers/flat_map.h" +#include "base/memory/weak_ptr.h" +#include "media/base/cdm_factory.h" +#include "media/base/media_export.h" +#include "media/base/ohos/ohos_media_drm_bridge_factory.h" +#include "media/base/provision_fetcher.h" + +namespace media { + +struct CdmConfig; + +class MEDIA_EXPORT OHOSCdmFactory final : public CdmFactory { + public: + OHOSCdmFactory(CreateFetcherCB create_fetcher_cb, + CreateStorageCB create_storage_cb); + + OHOSCdmFactory(const OHOSCdmFactory&) = delete; + OHOSCdmFactory& operator=(const OHOSCdmFactory&) = delete; + + ~OHOSCdmFactory() override; + + // CdmFactory implementation. + void Create(const CdmConfig& cdm_config, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb, + CdmCreatedCB cdm_created_cb) override; + + private: + // Callback for MediaDrmBridgeFactory::Create(). + void OnCdmCreated(uint32_t creation_id, + const scoped_refptr& cdm, + const std::string& error_message); + + CreateFetcherCB create_fetcher_cb_; + CreateStorageCB create_storage_cb_; + + uint32_t creation_id_ = 0; + + // Map between creation ID and PendingCreations. + using PendingCreation = + std::pair, CdmCreatedCB>; + base::flat_map pending_creations_; + + base::WeakPtrFactory weak_factory_{this}; +}; + +} // namespace media + +#endif // MEDIA_BASE_OHOS_OHOS_CDM_FACTORY_H_ diff --git a/media/base/ohos/ohos_media_codec_util.cc b/media/base/ohos/ohos_media_codec_util.cc index a24f73b9b2696686f24e35d875ec8efbcdef760a..dbd20c647f26e16f36992d0ab3bdca0d95ec825f 100644 --- a/media/base/ohos/ohos_media_codec_util.cc +++ b/media/base/ohos/ohos_media_codec_util.cc @@ -32,4 +32,127 @@ CapabilityData OHOSMediaCodecUtil::GetCodecCapability(const std::string& mime, return result; } +namespace { +const char kMp3MimeType[] = "audio/mpeg"; +const char kAacMimeType[] = "audio/mp4a-latm"; +const char kOpusMimeType[] = "audio/opus"; +const char kVorbisMimeType[] = "audio/vorbis"; +const char kFLACMimeType[] = "audio/flac"; +const char kAc3MimeType[] = "audio/ac3"; +const char kEac3MimeType[] = "audio/eac3"; +const char kBitstreamAudioMimeType[] = "audio/raw"; +const char kAvcMimeType[] = "video/avc"; +const char kDolbyVisionMimeType[] = "video/dolby-vision"; +const char kHevcMimeType[] = "video/hevc"; +const char kVp8MimeType[] = "video/x-vnd.on2.vp8"; +const char kVp9MimeType[] = "video/x-vnd.on2.vp9"; +const char kAv1MimeType[] = "video/av01"; +const char kDtsMimeType[] = "audio/vnd.dts"; +const char kDtseMimeType[] = "audio/vnd.dts;profile=lbr"; +const char kDtsxP2MimeType[] = "audio/vnd.dts.uhd;profile=p2"; +} // namespace + +// static +std::string OHOSMediaCodecUtil::CodecToOHOSMimeType(AudioCodec codec) { + return CodecToOHOSMimeType(codec, kUnknownSampleFormat); +} + +// static +std::string OHOSMediaCodecUtil::CodecToOHOSMimeType(AudioCodec codec, + SampleFormat sample_format) { + // Passthrough is possible for some bitstream formats. + const bool is_passthrough = sample_format == kSampleFormatDts || + sample_format == kSampleFormatDtsxP2 || + sample_format == kSampleFormatAc3 || + sample_format == kSampleFormatEac3 || + sample_format == kSampleFormatMpegHAudio; + + if (IsPassthroughAudioFormat(codec) || is_passthrough) + return kBitstreamAudioMimeType; + + switch (codec) { + case AudioCodec::kMP3: + return kMp3MimeType; + case AudioCodec::kVorbis: + return kVorbisMimeType; + case AudioCodec::kFLAC: + return kFLACMimeType; + case AudioCodec::kOpus: + return kOpusMimeType; + case AudioCodec::kAAC: + return kAacMimeType; + case AudioCodec::kAC3: + return kAc3MimeType; + case AudioCodec::kEAC3: + return kEac3MimeType; + case AudioCodec::kDTS: + return kDtsMimeType; + case AudioCodec::kDTSE: + return kDtseMimeType; + case AudioCodec::kDTSXP2: + return kDtsxP2MimeType; + default: + return std::string(); + } +} + +// static +std::string OHOSMediaCodecUtil::CodecToOHOSMimeType(VideoCodec codec) { + switch (codec) { + case VideoCodec::kH264: + return kAvcMimeType; + case VideoCodec::kHEVC: + return kHevcMimeType; + case VideoCodec::kVP8: + return kVp8MimeType; + case VideoCodec::kVP9: + return kVp9MimeType; + case VideoCodec::kDolbyVision: + return kDolbyVisionMimeType; + case VideoCodec::kAV1: + return kAv1MimeType; + default: + return std::string(); + } +} + +// static +bool OHOSMediaCodecUtil::IsPassthroughAudioFormat(AudioCodec codec) { + switch (codec) { + case AudioCodec::kAC3: + case AudioCodec::kEAC3: + case AudioCodec::kDTS: + case AudioCodec::kDTSXP2: + case AudioCodec::kMpegHAudio: + return true; + default: + return false; + } +} + +static bool CanDecodeInternal(const std::string& mime, bool is_secure) { + if (mime.empty()) + return false; + + std::shared_ptr data = + OhosAdapterHelper::GetInstance() + .GetMediaCodecListAdapter() + .GetCodecCapability(mime, false); + if (!data) { + return false; + } + return true; +} + +// static +bool OHOSMediaCodecUtil::CanDecode(VideoCodec codec, bool is_secure) { + std::string mime = CodecToOHOSMimeType(codec); + return CanDecodeInternal(mime, is_secure); +} + +// static +bool OHOSMediaCodecUtil::CanDecode(AudioCodec codec) { + std::string mime = CodecToOHOSMimeType(codec); + return CanDecodeInternal(mime, false); +} } // namespace media diff --git a/media/base/ohos/ohos_media_codec_util.h b/media/base/ohos/ohos_media_codec_util.h index a3cf28813a6a47eea6766d646410e079226e474f..243714019bc21a511c0f7b3c422716fa84244902 100644 --- a/media/base/ohos/ohos_media_codec_util.h +++ b/media/base/ohos/ohos_media_codec_util.h @@ -8,6 +8,11 @@ #include "media_codec_adapter.h" #include "ohos_adapter_helper.h" +#include "base/compiler_specific.h" +#include "media/base/audio_codecs.h" +#include "media/base/sample_format.h" +#include "media/base/video_codecs.h" + namespace media { using namespace OHOS::NWeb; using namespace std; @@ -22,6 +27,13 @@ class OHOSMediaCodecUtil { public: static CapabilityData GetCodecCapability(const std::string& mime, bool isCodec); + static std::string CodecToOHOSMimeType(AudioCodec codec); + static std::string CodecToOHOSMimeType(AudioCodec codec, + SampleFormat sample_format); + static std::string CodecToOHOSMimeType(VideoCodec codec); + static bool IsPassthroughAudioFormat(AudioCodec codec); + static bool CanDecode(VideoCodec codec, bool is_secure); + static bool CanDecode(AudioCodec codec); }; } // namespace media diff --git a/media/base/ohos/ohos_media_crypto_context.h b/media/base/ohos/ohos_media_crypto_context.h new file mode 100644 index 0000000000000000000000000000000000000000..e8c3b48ccea84b9c9a155b86d1ba5500abd933c1 --- /dev/null +++ b/media/base/ohos/ohos_media_crypto_context.h @@ -0,0 +1,33 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_OHOS_OHOS_MEDIA_CRYPTO_CONTEXT_H_ +#define MEDIA_BASE_OHOS_OHOS_MEDIA_CRYPTO_CONTEXT_H_ + +#include + +#include "base/functional/callback.h" +#include "media/base/media_export.h" + +namespace media { + +class MEDIA_EXPORT OHOSMediaCryptoContext { + public: + OHOSMediaCryptoContext() = default; + + OHOSMediaCryptoContext(const OHOSMediaCryptoContext&) = delete; + OHOSMediaCryptoContext& operator=(const OHOSMediaCryptoContext&) = delete; + + using OHOSMediaCryptoReadyCB = + base::OnceCallback; + + virtual ~OHOSMediaCryptoContext() = default; + + virtual void SetOHOSMediaCryptoReadyCB( + OHOSMediaCryptoReadyCB media_crypto_ready_cb) = 0; +}; + +} // namespace media + +#endif // MEDIA_BASE_OHOS_OHOS_MEDIA_CRYPTO_CONTEXT_H_ diff --git a/media/base/ohos/ohos_media_crypto_context_impl.cc b/media/base/ohos/ohos_media_crypto_context_impl.cc new file mode 100644 index 0000000000000000000000000000000000000000..ef4f7daa047029a7fbb9f59edca6b3f3068c7635 --- /dev/null +++ b/media/base/ohos/ohos_media_crypto_context_impl.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/ohos/ohos_media_crypto_context_impl.h" + +#include "media/base/ohos/ohos_media_drm_bridge.h" + +namespace media { + +OHOSMediaCryptoContextImpl::OHOSMediaCryptoContextImpl( + OHOSMediaDrmBridge* media_drm_bridge) + : media_drm_bridge_(media_drm_bridge) { + DCHECK(media_drm_bridge_); +} + +OHOSMediaCryptoContextImpl::~OHOSMediaCryptoContextImpl() = default; + +void OHOSMediaCryptoContextImpl::SetOHOSMediaCryptoReadyCB( + OHOSMediaCryptoReadyCB media_crypto_ready_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; + media_drm_bridge_->SetOHOSMediaCryptoReadyCB( + std::move(media_crypto_ready_cb)); + LOG(INFO) << "[NEU][CDM]" << __func__; +} +} // namespace media diff --git a/media/base/ohos/ohos_media_crypto_context_impl.h b/media/base/ohos/ohos_media_crypto_context_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..0b7ba0db4e3ae1e351ab8c78c482b3034764fab3 --- /dev/null +++ b/media/base/ohos/ohos_media_crypto_context_impl.h @@ -0,0 +1,36 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_OHOS_OHOS_MEDIA_CRYPTO_CONTEXT_IMPL_H_ +#define MEDIA_BASE_OHOS_OHOS_MEDIA_CRYPTO_CONTEXT_IMPL_H_ + +#include "base/memory/raw_ptr.h" +#include "media/base/media_export.h" +#include "media/base/ohos/ohos_media_crypto_context.h" + +namespace media { + +class OHOSMediaDrmBridge; + +class MEDIA_EXPORT OHOSMediaCryptoContextImpl final + : public OHOSMediaCryptoContext { + public: + explicit OHOSMediaCryptoContextImpl(OHOSMediaDrmBridge* media_drm_bridge); + + OHOSMediaCryptoContextImpl(const OHOSMediaCryptoContextImpl&) = delete; + OHOSMediaCryptoContextImpl& operator=(const OHOSMediaCryptoContextImpl&) = + delete; + + ~OHOSMediaCryptoContextImpl() override; + + void SetOHOSMediaCryptoReadyCB( + OHOSMediaCryptoReadyCB media_crypto_ready_cb) override; + + private: + const raw_ptr media_drm_bridge_; +}; + +} // namespace media + +#endif // MEDIA_BASE_OHOS_OHOS_MEDIA_CRYPTO_CONTEXT_IMPL_H_ diff --git a/media/base/ohos/ohos_media_drm_bridge.cc b/media/base/ohos/ohos_media_drm_bridge.cc new file mode 100644 index 0000000000000000000000000000000000000000..797c991e80d6fd7913551c84df397247551724d0 --- /dev/null +++ b/media/base/ohos/ohos_media_drm_bridge.cc @@ -0,0 +1,1048 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/ohos/ohos_media_drm_bridge.h" + +#include +#include +#include + +#include "base/feature_list.h" +#include "base/functional/bind.h" +#include "base/functional/callback_helpers.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/rand_util.h" +#include "base/ranges/algorithm.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/sys_byteorder.h" +#include "base/system/sys_info.h" +#include "base/task/single_thread_task_runner.h" +#include "media/base/cdm_key_information.h" +#include "media/base/logging_override_if_enabled.h" +#include "media/base/media_drm_key_type.h" +#include "media/base/media_switches.h" +#include "media/base/ohos/ohos_media_drm_bridge_client.h" +#include "media/base/ohos/ohos_media_drm_bridge_delegate.h" +#include "media/base/provision_fetcher.h" +#include "media/cdm/clear_key_cdm_common.h" +#include "third_party/widevine/cdm/widevine_cdm_common.h" + +#include "ohos_adapter_helper.h" + +namespace media { + +namespace { + +using CreateMediaDrmBridgeCB = + base::OnceCallback( + const std::string& /* origin_id */)>; + +enum class RequestType : uint32_t { + REQUEST_TYPE_INITIAL = 0, + REQUEST_TYPE_RENEWAL = 1, + REQUEST_TYPE_RELEASE = 2, +}; + +enum class KeyStatus : uint32_t { + KEY_STATUS_USABLE = 0, + KEY_STATUS_EXPIRED = 1, + KEY_STATUS_OUTPUT_NOT_ALLOWED = 2, + KEY_STATUS_PENDING = 3, + KEY_STATUS_INTERNAL_ERROR = 4, + KEY_STATUS_USABLE_IN_FUTURE = 5, // Added in API level 29. +}; + +std::string ConvertInitDataType(media::EmeInitDataType init_data_type) { + switch (init_data_type) { + case media::EmeInitDataType::WEBM: + return "video/webm"; + case media::EmeInitDataType::CENC: + return "video/mp4"; + case media::EmeInitDataType::KEYIDS: + return "keyids"; + default: + NOTREACHED(); + return "unknown"; + } +} + +OHOSMediaDrmBridge::OHOSMediaKeyType ConvertCdmSessionType( + CdmSessionType session_type) { + switch (session_type) { + case CdmSessionType::kTemporary: + return OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_ONLINE; + case CdmSessionType::kPersistentLicense: + return OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_OFFLINE; + + default: + LOG(WARNING) << "Unsupported session type " + << static_cast(session_type); + return OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_ONLINE; + } +} + +MediaDrmKeyType ConvertOHOSMediaKeyType( + OHOSMediaDrmBridge::OHOSMediaKeyType key_type) { + switch (key_type) { + case OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_OFFLINE: + return MediaDrmKeyType::OFFLINE; + case OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_ONLINE: + return MediaDrmKeyType::STREAMING; + case OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_RELEASE: + return MediaDrmKeyType::RELEASE; + default: + LOG(WARNING) << "Unsupported ohos media key type " + << static_cast(key_type); + return MediaDrmKeyType::STREAMING; + } +} + +OHOSMediaDrmBridge::OHOSMediaKeyType ConvertMediaDrmKeyType( + MediaDrmKeyType key_type) { + switch (key_type) { + case MediaDrmKeyType::OFFLINE: + return OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_OFFLINE; + case MediaDrmKeyType::STREAMING: + return OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_ONLINE; + case MediaDrmKeyType::RELEASE: + return OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_RELEASE; + default: + LOG(WARNING) << "Unsupported media key type " + << static_cast(key_type); + return OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_ONLINE; + } +} + +CdmMessageType GetMessageType(int32_t request_type) { + switch (request_type) { + case 1: // MEDIA_KEY_REQUEST_TYPE_INITIAL + return CdmMessageType::LICENSE_REQUEST; + case 2: // MEDIA_KEY_REQUEST_TYPE_RENEWAL + return CdmMessageType::LICENSE_RENEWAL; + case 3: // MEDIA_KEY_REQUEST_TYPE_RELEASE + return CdmMessageType::LICENSE_RELEASE; + case 0: // MEDIA_KEY_REQUEST_TYPE_UNKNOWN + case 4: // MEDIA_KEY_REQUEST_TYPE_NONE + case 5: // MEDIA_KEY_REQUEST_TYPE_UPDATE + default: + return CdmMessageType::LICENSE_REQUEST; + } + + NOTREACHED(); + return CdmMessageType::LICENSE_REQUEST; +} + +CdmKeyInformation::KeyStatus ConvertKeyStatus(KeyStatus key_status, + bool is_key_release) { + switch (key_status) { + case KeyStatus::KEY_STATUS_USABLE: + return CdmKeyInformation::USABLE; + case KeyStatus::KEY_STATUS_EXPIRED: + return is_key_release ? CdmKeyInformation::RELEASED + : CdmKeyInformation::EXPIRED; + case KeyStatus::KEY_STATUS_OUTPUT_NOT_ALLOWED: + return CdmKeyInformation::OUTPUT_RESTRICTED; + case KeyStatus::KEY_STATUS_PENDING: + return CdmKeyInformation::KEY_STATUS_PENDING; + case KeyStatus::KEY_STATUS_INTERNAL_ERROR: + return CdmKeyInformation::INTERNAL_ERROR; + case KeyStatus::KEY_STATUS_USABLE_IN_FUTURE: + return CdmKeyInformation::EXPIRED; + } + + NOTREACHED(); + return CdmKeyInformation::INTERNAL_ERROR; +} + +std::vector fromHexString(const std::string& hexString) { + std::vector data; + for (size_t i = 0; i < hexString.length(); i += 2) { + std::string byteString = hexString.substr(i, 2); + uint8_t byte = + static_cast(strtol(byteString.c_str(), nullptr, 16)); + data.push_back(byte); + } + return data; +} + +const uint8_t kWidevineUuid[16] = {0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, + 0x4A, 0xCE, 0xA3, 0xC8, 0x27, 0xDC, + 0xD5, 0x1D, 0x21, 0xED}; + +class OHOSDrmAdapterUtil { + public: + static OHOSDrmAdapterUtil& GetInstance(); + OHOSDrmAdapterUtil(); + ~OHOSDrmAdapterUtil() = default; + + UUID GetUUID(const std::string& key_system); + bool IsSupported(const std::string name); + bool IsSupported2(const std::string name, const std::string mimeType); + + private: + std::unique_ptr drm_adapter_ = nullptr; +}; + +OHOSDrmAdapterUtil& OHOSDrmAdapterUtil::GetInstance() { + static OHOSDrmAdapterUtil ohosAdapterUtil; + return ohosAdapterUtil; +} + +OHOSDrmAdapterUtil::OHOSDrmAdapterUtil() { + drm_adapter_ = + OHOS::NWeb::OhosAdapterHelper::GetInstance().CreateDrmAdapter(); +} + +UUID OHOSDrmAdapterUtil::GetUUID(const std::string& key_system) { + if (drm_adapter_) { + UUID uuid = drm_adapter_->GetUUID(kWidevineKeySystem); + return uuid; + } + return UUID(); +} + +bool OHOSDrmAdapterUtil::IsSupported(const std::string name) { + if (drm_adapter_) { + return drm_adapter_->IsSupported(name); + } + return false; +} + +bool OHOSDrmAdapterUtil::IsSupported2(const std::string name, + const std::string mimeType) { + if (drm_adapter_) { + return drm_adapter_->IsSupported2(name, mimeType); + } + return false; +} +#ifdef OHOS_ENABLE_WISEPLAY +constexpr char kWiseplayKeySystem[] = "com.wiseplay.drm"; +#endif + +class KeySystemManager { + public: + KeySystemManager(); + KeySystemManager(const KeySystemManager&) = delete; + KeySystemManager& operator=(const KeySystemManager&) = delete; + + UUID GetUUID(const std::string& key_system); + std::vector GetPlatformKeySystemNames(); + + private: + using KeySystemUuidMap = OHOSMediaDrmBridgeClient::KeySystemUuidMap; + + KeySystemUuidMap key_system_uuid_map_; +}; + +KeySystemManager::KeySystemManager() { + key_system_uuid_map_[kWidevineKeySystem] = + UUID(kWidevineUuid, kWidevineUuid + std::size(kWidevineUuid)); +#ifdef OHOS_ENABLE_WISEPLAY + UUID uuidWiseplay = + OHOSDrmAdapterUtil::GetInstance().GetUUID(kWiseplayKeySystem); + if (uuidWiseplay.size() > 0) { + key_system_uuid_map_[kWiseplayKeySystem] = uuidWiseplay; + } +#endif + // com.wiseplay.drm + OHOSMediaDrmBridgeClient* client = GetMediaDrmBridgeClient(); + if (client) { + client->AddKeySystemUUIDMappings(&key_system_uuid_map_); + } +} + +UUID KeySystemManager::GetUUID(const std::string& key_system) { + KeySystemUuidMap::iterator it = key_system_uuid_map_.find(key_system); + if (it == key_system_uuid_map_.end()) { + return UUID(); + } + return it->second; +} + +std::vector KeySystemManager::GetPlatformKeySystemNames() { + std::vector key_systems; + for (KeySystemUuidMap::iterator it = key_system_uuid_map_.begin(); + it != key_system_uuid_map_.end(); ++it) { + if (it->first != kWidevineKeySystem) { + key_systems.push_back(it->first); + } + } + return key_systems; +} + +KeySystemManager* GetKeySystemManager() { + static KeySystemManager* ksm = new KeySystemManager(); + return ksm; +} + +bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system, + const std::string& container_mime_type) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (key_system.empty()) { + NOTREACHED(); + return false; + } + + UUID scheme_uuid = GetKeySystemManager()->GetUUID(key_system); + if (scheme_uuid.empty()) { + LOG(ERROR) << "[NEU]Cannot get UUID for key system " << key_system; + return false; + } + + bool supported = false; + if (!container_mime_type.empty()) { + supported = OHOSDrmAdapterUtil::GetInstance().IsSupported2( + key_system, container_mime_type); + } else { + supported = OHOSDrmAdapterUtil::GetInstance().IsSupported(key_system); + } + return supported; +} +} // namespace + +OHOSDrmCallback::OHOSDrmCallback(OHOSMediaDrmBridge* media_drm_bridge) + : media_drm_bridge_(media_drm_bridge) { + DCHECK(media_drm_bridge_); +} + +OHOSDrmCallback::~OHOSDrmCallback() {} + +void OHOSDrmCallback::UpdateDrmData(uint8_t* info, + int32_t infoLen, + char* extra) {} + +void OHOSDrmCallback::OnSessionMessage(std::string sessionId, + int32_t& type, + std::vector message) { + if (media_drm_bridge_) { + media_drm_bridge_->OnSessionMessage(sessionId, type, message); + } +} + +void OHOSDrmCallback::OnProvisionRequest(std::string defaultUrl, + std::string requestData) { + if (media_drm_bridge_) { + media_drm_bridge_->OnProvisionRequest(defaultUrl, requestData); + } +} + +void OHOSDrmCallback::OnProvisioningComplete(bool success) { + if (media_drm_bridge_) { + media_drm_bridge_->OnProvisioningComplete(success); + } +} + +void OHOSDrmCallback::OnMediaKeySessionReady(void* session) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (media_drm_bridge_) { + media_drm_bridge_->OnOHOSMediaCryptoReady(session); + LOG(INFO) << "[NEU][CDM]" << __func__; + } +} + +void OHOSDrmCallback::OnPromiseRejected(uint32_t promiseId, + std::string errorMessage) { + if (media_drm_bridge_) { + media_drm_bridge_->OnPromiseRejected(promiseId, errorMessage); + } +} + +void OHOSDrmCallback::OnPromiseResolved(uint32_t promiseId) { + if (media_drm_bridge_) { + media_drm_bridge_->OnPromiseResolved(promiseId); + } +} + +void OHOSDrmCallback::OnPromiseResolvedWithSession(uint32_t promiseId, + std::string sessionId) { + if (media_drm_bridge_) { + media_drm_bridge_->OnPromiseResolvedWithSession(promiseId, sessionId); + } +} + +void OHOSDrmCallback::OnSessionClosed(std::string session_id) { + if (media_drm_bridge_) { + media_drm_bridge_->OnSessionClosed(session_id); + } +} + +void OHOSDrmCallback::OnSessionKeysChange(std::string session_id, + std::vector keyIdArray, + std::vector statusArray, + bool has_additional_usable_key, + bool is_key_release) { + if (media_drm_bridge_) { + media_drm_bridge_->OnSessionKeysChange(session_id, keyIdArray, statusArray, + has_additional_usable_key, + is_key_release); + } +} + +void OHOSDrmCallback::OnSessionExpirationUpdate(std::string session_id, + uint64_t expiration_time) { + if (media_drm_bridge_) { + media_drm_bridge_->OnSessionExpirationUpdate(session_id, expiration_time); + } +} + +void OHOSDrmCallback::OnStorageProvisioned() { + if (media_drm_bridge_) { + media_drm_bridge_->OnStorageProvisioned(); + } +} + +void OHOSDrmCallback::OnStorageSaveInfo(std::vector ketSetId, + std::string mimeType, + std::string sessionId, + int32_t key_type) { + if (media_drm_bridge_) { + media_drm_bridge_->OnStorageSaveInfo(ketSetId, mimeType, sessionId, + key_type); + } +} + +void OHOSDrmCallback::OnStorageLoadInfo(std::string session_id) { + if (media_drm_bridge_) { + media_drm_bridge_->OnStorageLoadInfo(session_id); + } +} + +void OHOSDrmCallback::OnStorageClearInfoForKeyRelease(std::string session_id) { + if (media_drm_bridge_) { + media_drm_bridge_->OnStorageClearInfoForKeyRelease(session_id); + } +} + +void OHOSDrmCallback::OnStorageClearInfoForLoadFail(std::string session_id) { + if (media_drm_bridge_) { + media_drm_bridge_->OnStorageClearInfoForLoadFail(session_id); + } +} + +// static +bool OHOSMediaDrmBridge::IsKeySystemSupported(const std::string& key_system) { + return IsKeySystemSupportedWithTypeImpl(key_system, ""); +} + +// static +bool OHOSMediaDrmBridge::IsPersistentLicenseTypeSupported( + const std::string& /* key_system */) { + return true; +} + +// static +bool OHOSMediaDrmBridge::IsKeySystemSupportedWithType( + const std::string& key_system, + const std::string& container_mime_type) { + DCHECK(!container_mime_type.empty()) << "Call IsKeySystemSupported instead"; + + return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type); +} + +// static +std::vector OHOSMediaDrmBridge::GetPlatformKeySystemNames() { + return GetKeySystemManager()->GetPlatformKeySystemNames(); +} + +// static +std::vector OHOSMediaDrmBridge::GetUUID( + const std::string& key_system) { + return GetKeySystemManager()->GetUUID(key_system); +} + +// static +scoped_refptr OHOSMediaDrmBridge::CreateInternal( + const std::vector& scheme_uuid, + const std::string& origin_id, + SecurityLevel security_level, + bool requires_media_crypto, + std::unique_ptr storage, + CreateFetcherCB create_fetcher_cb, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(!scheme_uuid.empty()); + scoped_refptr media_drm_bridge(new OHOSMediaDrmBridge( + scheme_uuid, origin_id, security_level, requires_media_crypto, + std::move(storage), std::move(create_fetcher_cb), session_message_cb, + session_closed_cb, session_keys_change_cb, session_expiration_update_cb)); + + return media_drm_bridge; +} + +void OHOSMediaDrmBridge::SetServerCertificate( + const std::vector& certificate, + std::unique_ptr promise) { + promise->reject(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, + "SetServerCertificate() is not supported."); +} + +std::string GenerateSessionId() { + char random_bytes[16]; + base::RandBytes(random_bytes, 16); + return base::HexEncode(random_bytes, 16); +} + +void OHOSMediaDrmBridge::CreateSessionAndGenerateRequest( + CdmSessionType session_type, + media::EmeInitDataType init_data_type, + const std::vector& init_data, + std::unique_ptr promise) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(task_runner_->BelongsToCurrentThread()); + + uint32_t promise_id = + cdm_promise_adapter_.SavePromise(std::move(promise), __func__); + + OHOSMediaDrmBridgeClient* client = GetMediaDrmBridgeClient(); + std::vector init_data_from_delegate; + std::vector optional_parameters_from_delegate; + if (client) { + LOG(INFO) << "[NEU][CDM]" << __func__; + OHOSMediaDrmBridgeDelegate* delegate = + client->GetMediaDrmBridgeDelegate(scheme_uuid_); + if (delegate) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (!delegate->OnCreateSession(init_data_type, init_data, + &init_data_from_delegate, + &optional_parameters_from_delegate)) { + RejectPromise(promise_id, CdmPromise::Exception::TYPE_ERROR, + "Invalid init data."); + return; + } + } + } + + std::string mime_type = ConvertInitDataType(init_data_type); + uint32_t key_type = + static_cast(ConvertCdmSessionType(session_type)); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", " << mime_type << ", " + << key_type; + + std::string session_id = GenerateSessionId(); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", session_id:" << session_id + << ", mime_type:" << mime_type; + if (ohos_drm_adapter_) { + ohos_drm_adapter_->GenerateMediaKeyRequest(session_id, key_type, + init_data.size(), init_data, + mime_type, promise_id); + } + LOG(INFO) << "[NEU][CDM]" << __func__; +} + +void OHOSMediaDrmBridge::LoadSession( + CdmSessionType session_type, + const std::string& session_id, + std::unique_ptr promise) { + DCHECK(task_runner_->BelongsToCurrentThread()); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", session_id:" << session_id; + + DCHECK(IsPersistentLicenseTypeSupported("")); + LOG(INFO) << "[NEU][CDM]" << __func__ + << ", session_type:" << (int32_t)session_type; + uint32_t promise_id = + cdm_promise_adapter_.SavePromise(std::move(promise), __func__); + + if (session_type != CdmSessionType::kPersistentLicense) { + LOG(INFO) << "[NEU][CDM]" << __func__; + RejectPromise(promise_id, CdmPromise::Exception::NOT_SUPPORTED_ERROR, + "LoadSession() is only supported for 'persistent-license'."); + return; + } + + if (ohos_drm_adapter_) { + LOG(INFO) << "[NEU][CDM]" << __func__; + ohos_drm_adapter_->LoadSession(promise_id, session_id); + LOG(INFO) << "[NEU][CDM]" << __func__; + } else { + RejectPromise(promise_id, CdmPromise::Exception::INVALID_STATE_ERROR, + "OHOSDrmAdapter is nullptr."); + } +} + +void OHOSMediaDrmBridge::UpdateSession( + const std::string& session_id, + const std::vector& response, + std::unique_ptr promise) { + DCHECK(task_runner_->BelongsToCurrentThread()); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", session_id: " << session_id; + + uint32_t promise_id = + cdm_promise_adapter_.SavePromise(std::move(promise), __func__); + + if (ohos_drm_adapter_) { + ohos_drm_adapter_->UpdateSession(promise_id, session_id, response); + } else { + RejectPromise(promise_id, CdmPromise::Exception::INVALID_STATE_ERROR, + "OHOSDrmAdapter is nullptr."); + } +} + +void OHOSMediaDrmBridge::CloseSession( + const std::string& session_id, + std::unique_ptr promise) { + DCHECK(task_runner_->BelongsToCurrentThread()); + LOG(INFO) << "[NEU][CDM]" << __func__; + uint32_t promise_id = + cdm_promise_adapter_.SavePromise(std::move(promise), __func__); + if (ohos_drm_adapter_) { + LOG(INFO) << "[NEU][CDM]" << __func__; + ohos_drm_adapter_->CloseSession(promise_id, session_id); + } else { + RejectPromise(promise_id, CdmPromise::Exception::INVALID_STATE_ERROR, + "OHOSDrmAdapter is nullptr."); + } +} + +void OHOSMediaDrmBridge::RemoveSession( + const std::string& session_id, + std::unique_ptr promise) { + DCHECK(task_runner_->BelongsToCurrentThread()); + LOG(INFO) << "[NEU][CDM]" << __func__; + uint32_t promise_id = + cdm_promise_adapter_.SavePromise(std::move(promise), __func__); + if (ohos_drm_adapter_) { + ohos_drm_adapter_->RemoveSession(promise_id, session_id); + LOG(INFO) << "[NEU][CDM]" << __func__; + } else { + RejectPromise(promise_id, CdmPromise::Exception::INVALID_STATE_ERROR, + "OHOSDrmAdapter is nullptr."); + } +} + +CdmContext* OHOSMediaDrmBridge::GetCdmContext() { + LOG(INFO) << "[NEU][CDM]" << __func__; + return this; +} + +void OHOSMediaDrmBridge::DeleteOnCorrectThread() const { + DVLOG(1) << __func__; + + if (!task_runner_->BelongsToCurrentThread()) { + task_runner_->DeleteSoon(FROM_HERE, this); + } else { + delete this; + } +} + +std::unique_ptr OHOSMediaDrmBridge::RegisterEventCB( + EventCB event_cb) { + return event_callbacks_.Register(std::move(event_cb)); +} + +OHOSMediaCryptoContext* OHOSMediaDrmBridge::GetOHOSMediaCryptoContext() { + return &media_crypto_context_; +} + +bool OHOSMediaDrmBridge::IsSecureCodecRequired() { + if (base::ranges::equal(scheme_uuid_, kWidevineUuid)) { + return SECURITY_LEVEL_1 == GetSecurityLevel(); + } + return false; +} + +void OHOSMediaDrmBridge::Provision( + base::OnceCallback provisioning_complete_cb) {} + +void OHOSMediaDrmBridge::Unprovision() {} + +void OHOSMediaDrmBridge::ResolvePromise(uint32_t promise_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; + cdm_promise_adapter_.ResolvePromise(promise_id); +} + +void OHOSMediaDrmBridge::ResolvePromiseWithSession( + uint32_t promise_id, + const std::string& session_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; + cdm_promise_adapter_.ResolvePromise(promise_id, session_id); +} + +void OHOSMediaDrmBridge::RejectPromise(uint32_t promise_id, + CdmPromise::Exception exception_code, + const std::string& error_message) { + LOG(INFO) << "[NEU][CDM]" << __func__; + cdm_promise_adapter_.RejectPromise(promise_id, exception_code, 0, + error_message); +} + +void OHOSMediaDrmBridge::SetOHOSMediaCryptoReadyCB( + OHOSMediaCryptoReadyCB media_crypto_ready_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (!task_runner_->BelongsToCurrentThread()) { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&OHOSMediaDrmBridge::SetOHOSMediaCryptoReadyCB, + weak_factory_.GetWeakPtr(), + std::move(media_crypto_ready_cb))); + return; + } + LOG(INFO) << "[NEU][CDM]" << __func__; + if (!media_crypto_ready_cb) { + media_crypto_ready_cb_.Reset(); + return; + } + + DCHECK(!media_crypto_ready_cb_); + media_crypto_ready_cb_ = std::move(media_crypto_ready_cb); + LOG(INFO) << "[NEU][CDM]" << __func__; + if (!ohos_media_key_session_) { + LOG(INFO) << "[NEU][CDM]" << __func__; + return; + } + LOG(INFO) << "[NEU][CDM]" << __func__; + std::move(media_crypto_ready_cb_) + .Run(ohos_media_key_session_, IsSecureCodecRequired()); +} + +void OHOSMediaDrmBridge::OnOHOSMediaCryptoReady(void* session) { + DCHECK(task_runner_->BelongsToCurrentThread()); + LOG(INFO) << "[NEU][CDM]" << __func__; + + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&OHOSMediaDrmBridge::NotifyMediaCryptoReady, + weak_factory_.GetWeakPtr(), session)); +} + +void OHOSMediaDrmBridge::OnProvisionRequest(std::string defaultUrl, + std::string requestData) { + LOG(INFO) << "[NEU][CDM]" << __func__; + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&OHOSMediaDrmBridge::SendProvisioningRequest, + weak_factory_.GetWeakPtr(), GURL(defaultUrl), + std::move(requestData))); +} + +void OHOSMediaDrmBridge::OnProvisioningComplete(bool success) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(provisioning_complete_cb_); + task_runner_->PostTask( + FROM_HERE, base::BindOnce(std::move(provisioning_complete_cb_), success)); +} + +void OHOSMediaDrmBridge::OnPromiseResolved(uint32_t promise_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&OHOSMediaDrmBridge::ResolvePromise, + weak_factory_.GetWeakPtr(), promise_id)); +} + +void OHOSMediaDrmBridge::OnPromiseResolvedWithSession(uint32_t promise_id, + std::string session_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&OHOSMediaDrmBridge::ResolvePromiseWithSession, + weak_factory_.GetWeakPtr(), promise_id, + std::move(session_id))); +} + +void OHOSMediaDrmBridge::OnPromiseRejected(uint32_t promise_id, + std::string error_message) { + LOG(INFO) << "[NEU][CDM]" << __func__; + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&OHOSMediaDrmBridge::RejectPromise, + weak_factory_.GetWeakPtr(), promise_id, + CdmPromise::Exception::NOT_SUPPORTED_ERROR, + error_message)); +} + +void OHOSMediaDrmBridge::OnStorageProvisionedResult(bool result) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (ohos_drm_adapter_) { + ohos_drm_adapter_->StorageProvisionedResult(result); + } +} + +void OHOSMediaDrmBridge::OnStorageProvisioned() { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (storage_) { + storage_->OnProvisioned( + base::BindOnce(&OHOSMediaDrmBridge::OnStorageProvisionedResult, + weak_factory_.GetWeakPtr())); + } +} + +void OHOSMediaDrmBridge::OnStorageSaveInfoUpdateResult(bool result) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (ohos_drm_adapter_) { + ohos_drm_adapter_->StorageSaveInfoResult(result, -1); + } +} + +void OHOSMediaDrmBridge::OnStorageSaveInfoRemoveResult(bool result) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (ohos_drm_adapter_) { + ohos_drm_adapter_->StorageSaveInfoResult( + result, + OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_RELEASE); + } +} + +void OHOSMediaDrmBridge::OnStorageSaveInfo(std::vector ket_set_id, + std::string mime_type, + std::string session_id, + int32_t key_type) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (storage_) { + MediaDrmKeyType media_drm_key_type = ConvertOHOSMediaKeyType( + static_cast(key_type)); + if (key_type == + OHOSMediaDrmBridge::OHOSMediaKeyType::OHOS_MEDIA_KEY_TYPE_RELEASE) { + LOG(INFO) << "[NEU][CDM]" << __func__; + storage_->OnSaveInfo( + ket_set_id, mime_type, session_id, + static_cast(media_drm_key_type), + base::BindOnce(&OHOSMediaDrmBridge::OnStorageSaveInfoRemoveResult, + weak_factory_.GetWeakPtr())); + } else { + LOG(INFO) << "[NEU][CDM]" << __func__; + storage_->OnSaveInfo( + ket_set_id, mime_type, session_id, + static_cast(media_drm_key_type), + base::BindOnce(&OHOSMediaDrmBridge::OnStorageSaveInfoUpdateResult, + weak_factory_.GetWeakPtr())); + } + } +} + +void OHOSMediaDrmBridge::OnStorageLoadInfoResult( + std::string session_id, + std::vector key_set_id, + std::string mime, + uint32_t key_type) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (ohos_drm_adapter_) { + OHOSMediaDrmBridge::OHOSMediaKeyType ohos_media_key_type = + ConvertMediaDrmKeyType(static_cast(key_type)); + ohos_drm_adapter_->StorageLoadInfoResult( + session_id, key_set_id, mime, + static_cast(ohos_media_key_type)); + } +} + +void OHOSMediaDrmBridge::OnStorageLoadInfo(std::string session_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (storage_) { + LOG(INFO) << "[NEU][CDM]" << __func__; + storage_->OnLoadInfo( + session_id, base::BindOnce(&OHOSMediaDrmBridge::OnStorageLoadInfoResult, + weak_factory_.GetWeakPtr())); + } +} + +void OHOSMediaDrmBridge::OnStorageClearInfoForKeyReleaseResult(bool result) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (ohos_drm_adapter_) { + ohos_drm_adapter_->StorageClearInfoResult( + result, OHOSClearInfoType::OHOS_KEY_RELEASE); + } +} + +void OHOSMediaDrmBridge::OnStorageClearInfoForKeyRelease( + std::string session_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (storage_) { + storage_->OnClearInfo( + session_id, + base::BindOnce( + &OHOSMediaDrmBridge::OnStorageClearInfoForKeyReleaseResult, + weak_factory_.GetWeakPtr())); + } +} + +void OHOSMediaDrmBridge::OnStorageClearInfoForLoadFailResult(bool result) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (ohos_drm_adapter_) { + ohos_drm_adapter_->StorageClearInfoResult( + result, OHOSClearInfoType::OHOS_LOAD_FAIL); + } +} + +void OHOSMediaDrmBridge::OnStorageClearInfoForLoadFail(std::string session_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (storage_) { + storage_->OnClearInfo( + session_id, + base::BindOnce(&OHOSMediaDrmBridge::OnStorageClearInfoForLoadFailResult, + weak_factory_.GetWeakPtr())); + } +} + +void OHOSMediaDrmBridge::OnSessionMessage(std::string session_id, + uint32_t message_type, + std::vector message) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", session_id:" << session_id + << ", message:" << message.data(); + CdmMessageType cdm_message_type = GetMessageType(message_type); + LOG(INFO) << "[NEU][CDM]" << __func__ << ", message_type: " << message_type + << ", cdm_message_type:" << (uint32_t)cdm_message_type; + task_runner_->PostTask( + FROM_HERE, base::BindOnce(session_message_cb_, std::move(session_id), + cdm_message_type, message)); +} + +void OHOSMediaDrmBridge::OnSessionClosed(std::string session_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; + task_runner_->PostTask( + FROM_HERE, base::BindOnce(session_closed_cb_, std::move(session_id), + CdmSessionClosedReason::kClose)); +} + +void OHOSMediaDrmBridge::OnSessionKeysChange( + std::string session_id, + std::vector keyIdArray, + std::vector statusArray, + bool has_additional_usable_key, + bool is_key_release) { + LOG(INFO) << "[NEU][CDM]" << __func__; + CdmKeysInfo cdm_keys_info; + if (keyIdArray.size() == statusArray.size()) { + for (uint32_t i = 0; i < keyIdArray.size(); i++) { + std::string key_id = keyIdArray[i]; + uint32_t status = statusArray[i]; + + CdmKeyInformation::KeyStatus key_status = + ConvertKeyStatus(static_cast(status), is_key_release); + cdm_keys_info.push_back(std::make_unique( + fromHexString(key_id), key_status, 0)); + } + } + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(session_keys_change_cb_, std::move(session_id), + has_additional_usable_key, std::move(cdm_keys_info))); + + if (has_additional_usable_key) { + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&OHOSMediaDrmBridge::OnHasAdditionalUsableKey, + weak_factory_.GetWeakPtr())); + } +} + +void OHOSMediaDrmBridge::OnSessionExpirationUpdate(std::string session_id, + uint64_t expiry_time_ms) { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(session_expiration_update_cb_, std::move(session_id), + base::Time::FromDoubleT(expiry_time_ms / 1000.0))); +} + +OHOSMediaDrmBridge::OHOSMediaDrmBridge( + const std::vector& scheme_uuid, + const std::string& origin_id, + SecurityLevel security_level, + bool requires_media_crypto, + std::unique_ptr storage, + const CreateFetcherCB& create_fetcher_cb, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb) + : scheme_uuid_(scheme_uuid), + storage_(std::move(storage)), + create_fetcher_cb_(create_fetcher_cb), + session_message_cb_(session_message_cb), + session_closed_cb_(session_closed_cb), + session_keys_change_cb_(session_keys_change_cb), + session_expiration_update_cb_(session_expiration_update_cb), + task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()), + media_crypto_context_(this) { + LOG(INFO) << "[NEU][CDM]" << __func__; + ohos_drm_adapter_ = + OHOS::NWeb::OhosAdapterHelper::GetInstance().CreateDrmAdapter(); + int32_t ret = -1; + if (ohos_drm_adapter_) { + task_runner_ = base::SingleThreadTaskRunner::GetCurrentDefault(); + auto drmCallback = std::make_unique(this); + ohos_drm_adapter_->RegistDrmCallback(std::move(drmCallback)); + + if (scheme_uuid == GetKeySystemManager()->GetUUID(kWidevineKeySystem)) { + ret = ohos_drm_adapter_->CreateKeySystem(kWidevineKeySystem, + security_level); +#ifdef OHOS_ENABLE_WISEPLAY + } else if (scheme_uuid == + GetKeySystemManager()->GetUUID(kWiseplayKeySystem)) { + ret = ohos_drm_adapter_->CreateKeySystem(kWiseplayKeySystem, + security_level); +#endif + } + } +} + +OHOSMediaDrmBridge::~OHOSMediaDrmBridge() { + DCHECK(task_runner_->BelongsToCurrentThread()); + if (ohos_drm_adapter_) { + ohos_drm_adapter_->ReleaseMediaKeySystem(); + } + if (media_crypto_ready_cb_) { + std::move(media_crypto_ready_cb_).Run(nullptr, false); + } + cdm_promise_adapter_.Clear(CdmPromiseAdapter::ClearReason::kDestruction); +} + +OHOSMediaDrmBridge::SecurityLevel OHOSMediaDrmBridge::GetSecurityLevel() { + OHOSMediaDrmBridge::SecurityLevel securityLevel = + SecurityLevel::SECURITY_LEVEL_DEFAULT; + if (ohos_drm_adapter_) { + int32_t level = ohos_drm_adapter_->GetSecurityLevel(); + securityLevel = static_cast(level); + } + return securityLevel; +} + +void OHOSMediaDrmBridge::NotifyMediaCryptoReady(void* session) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(task_runner_->BelongsToCurrentThread()); + ohos_media_key_session_ = session; + if (!media_crypto_ready_cb_) { + return; + } + LOG(INFO) << "[NEU][CDM]" << __func__; + std::move(media_crypto_ready_cb_) + .Run(ohos_media_key_session_, IsSecureCodecRequired()); + LOG(INFO) << "[NEU][CDM]" << __func__; +} + +void OHOSMediaDrmBridge::SendProvisioningRequest( + const GURL& default_url, + const std::string& request_data) { + DCHECK(task_runner_->BelongsToCurrentThread()); + DVLOG(1) << __func__; + + DCHECK(!provision_fetcher_) << "At most one provision request at any time."; + DCHECK(create_fetcher_cb_); + provision_fetcher_ = create_fetcher_cb_.Run(); + + provision_fetcher_->Retrieve( + default_url, request_data, + base::BindOnce(&OHOSMediaDrmBridge::ProcessProvisionResponse, + weak_factory_.GetWeakPtr())); +} + +void OHOSMediaDrmBridge::ProcessProvisionResponse(bool success, + const std::string& response) { + DCHECK(task_runner_->BelongsToCurrentThread()); + DCHECK(provision_fetcher_) << "No provision request pending."; + + provision_fetcher_.reset(); + + if (!success) { + LOG(ERROR) << "Device provision failure: can't get server response"; + } + + if (ohos_drm_adapter_) { + ohos_drm_adapter_->ProcessKeySystemResponse(response, success); + } +} + +void OHOSMediaDrmBridge::OnHasAdditionalUsableKey() { + DCHECK(task_runner_->BelongsToCurrentThread()); + event_callbacks_.Notify(Event::kHasAdditionalUsableKey); +} +} // namespace media diff --git a/media/base/ohos/ohos_media_drm_bridge.h b/media/base/ohos/ohos_media_drm_bridge.h new file mode 100644 index 0000000000000000000000000000000000000000..47ffd6006636651efbeb92ca41c517223a55976f --- /dev/null +++ b/media/base/ohos/ohos_media_drm_bridge.h @@ -0,0 +1,265 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_H_ +#define MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_H_ + +#include + +#include +#include +#include + +#include "base/functional/callback.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/task/sequenced_task_runner_helpers.h" +#include "media/base/callback_registry.h" +#include "media/base/cdm_context.h" +#include "media/base/cdm_promise.h" +#include "media/base/cdm_promise_adapter.h" +#include "media/base/content_decryption_module.h" +#include "media/base/media_drm_storage.h" +#include "media/base/media_export.h" +#include "media/base/ohos/ohos_media_crypto_context.h" +#include "media/base/ohos/ohos_media_crypto_context_impl.h" +#include "media/base/ohos/ohos_media_drm_storage_bridge.h" +#include "media/base/provision_fetcher.h" +#include "url/origin.h" + +#include "drm_adapter.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace media { + +class MEDIA_EXPORT OHOSMediaDrmBridge : public ContentDecryptionModule, + public CdmContext { + public: + enum SecurityLevel { + SECURITY_LEVEL_DEFAULT = 0, + SECURITY_LEVEL_1 = 1, + SECURITY_LEVEL_3 = 3, + }; + + enum OHOSMediaKeyType { + OHOS_MEDIA_KEY_TYPE_OFFLINE = 0, + OHOS_MEDIA_KEY_TYPE_ONLINE, + OHOS_MEDIA_KEY_TYPE_RELEASE, + }; + + enum OHOSClearInfoType { + OHOS_KEY_RELEASE = 0, + OHOS_LOAD_FAIL, + }; + + using OHOSMediaCryptoReadyCB = OHOSMediaCryptoContext::OHOSMediaCryptoReadyCB; + + static bool IsKeySystemSupported(const std::string& key_system); + static bool IsKeySystemSupportedWithType( + const std::string& key_system, + const std::string& container_mime_type); + static bool IsPerApplicationProvisioningSupported() { + return false; + }; // TBD... + static bool IsPersistentLicenseTypeSupported(const std::string& key_system); + static std::vector GetPlatformKeySystemNames(); + static std::vector GetUUID(const std::string& key_system); + + OHOSMediaDrmBridge(const OHOSMediaDrmBridge&) = delete; + OHOSMediaDrmBridge& operator=(const OHOSMediaDrmBridge&) = delete; + + void SetServerCertificate( + const std::vector& certificate, + std::unique_ptr promise) override; + void CreateSessionAndGenerateRequest( + CdmSessionType session_type, + media::EmeInitDataType init_data_type, + const std::vector& init_data, + std::unique_ptr promise) override; + void LoadSession( + CdmSessionType session_type, + const std::string& session_id, + std::unique_ptr promise) override; + void UpdateSession(const std::string& session_id, + const std::vector& response, + std::unique_ptr promise) override; + void CloseSession(const std::string& session_id, + std::unique_ptr promise) override; + void RemoveSession(const std::string& session_id, + std::unique_ptr promise) override; + CdmContext* GetCdmContext() override; + void DeleteOnCorrectThread() const override; + + std::unique_ptr RegisterEventCB( + EventCB event_cb) override; + + OHOSMediaCryptoContext* GetOHOSMediaCryptoContext() override; + + void Provision(base::OnceCallback provisioning_complete_cb); + void Unprovision(); + + bool IsSecureCodecRequired(); + + void ResolvePromise(uint32_t promise_id); + void ResolvePromiseWithSession(uint32_t promise_id, + const std::string& session_id); + void RejectPromise(uint32_t promise_id, + CdmPromise::Exception exception_code, + const std::string& error_message); + + void SetOHOSMediaCryptoReadyCB(OHOSMediaCryptoReadyCB media_crypto_ready_cb); + void OnOHOSMediaCryptoReady(void* session); + + void OnProvisionRequest(std::string defaultUrl, std::string requestData); + void OnProvisioningComplete(bool success); + + void OnPromiseResolved(uint32_t promise_id); + void OnPromiseResolvedWithSession(uint32_t promise_id, + std::string session_id); + + void OnPromiseRejected(uint32_t promise_id, std::string error_message); + + void OnStorageProvisioned(); + void OnStorageProvisionedResult(bool result); + void OnStorageSaveInfo(std::vector ket_set_id, + std::string mime_type, + std::string session_id, + int32_t key_type); + void OnStorageSaveInfoUpdateResult(bool result); + void OnStorageSaveInfoRemoveResult(bool result); + + void OnStorageLoadInfo(std::string session_id); + void OnStorageLoadInfoResult(std::string session_id, + std::vector key_set_id, + std::string mime, + uint32_t key_type); + + void OnStorageClearInfoForKeyRelease(std::string session_id); + void OnStorageClearInfoForKeyReleaseResult(bool result); + + void OnStorageClearInfoForLoadFail(std::string session_id); + void OnStorageClearInfoForLoadFailResult(bool result); + + void OnSessionMessage(std::string session_id, + uint32_t message_type, + std::vector message); + void OnSessionClosed(std::string session_id); + + void OnSessionKeysChange(std::string session_id, + std::vector key_id_array, + std::vector status_array, + bool has_additional_usable_key, + bool is_key_release); + + void OnSessionExpirationUpdate(std::string session_id, + uint64_t expiry_time_ms); + + private: + friend class OHOSMediaDrmBridgeFactory; + friend class base::DeleteHelper; + + static scoped_refptr CreateInternal( + const std::vector& scheme_uuid, + const std::string& origin_id, + SecurityLevel security_level, + bool requires_media_crypto, + std::unique_ptr storage, + CreateFetcherCB create_fetcher_cb, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb); + + OHOSMediaDrmBridge( + const std::vector& scheme_uuid, + const std::string& origin_id, + SecurityLevel security_level, + bool requires_media_crypto, + std::unique_ptr storage, + const CreateFetcherCB& create_fetcher_cb, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb); + + ~OHOSMediaDrmBridge() override; + + SecurityLevel GetSecurityLevel(); + void NotifyMediaCryptoReady(void* session); + void SendProvisioningRequest(const GURL& default_url, + const std::string& request_data); + void ProcessProvisionResponse(bool success, const std::string& response); + void OnHasAdditionalUsableKey(); + std::vector scheme_uuid_; + std::unique_ptr storage_; + CreateFetcherCB create_fetcher_cb_; + std::unique_ptr provision_fetcher_; + base::OnceCallback provisioning_complete_cb_; + + SessionMessageCB session_message_cb_; + SessionClosedCB session_closed_cb_; + SessionKeysChangeCB session_keys_change_cb_; + SessionExpirationUpdateCB session_expiration_update_cb_; + + OHOSMediaCryptoReadyCB media_crypto_ready_cb_; + CallbackRegistry event_callbacks_; + CdmPromiseAdapter cdm_promise_adapter_; + scoped_refptr task_runner_; + OHOSMediaCryptoContextImpl media_crypto_context_; + + base::WeakPtrFactory weak_factory_{this}; + + std::unique_ptr ohos_drm_adapter_; + OHOS::NWeb::OHOSMediaKeySession ohos_media_key_session_; +}; + +class OHOSDrmCallback : public OHOS::NWeb::DrmCallbackAdapter { + public: + OHOSDrmCallback(OHOSMediaDrmBridge* media_drm_bridge); + virtual ~OHOSDrmCallback(); + OHOSDrmCallback(const OHOSDrmCallback&) = delete; + OHOSDrmCallback& operator=(const OHOSDrmCallback&) = delete; + + void UpdateDrmData(uint8_t* info, int32_t infoLen, char* extra) override; + void OnSessionMessage(std::string session_id, + int32_t& type, + std::vector message) override; + void OnProvisionRequest(std::string defaultUrl, + std::string requestData) override; + void OnProvisioningComplete(bool success) override; + void OnMediaKeySessionReady(void* session) override; + void OnPromiseRejected(uint32_t promise_id, + std::string error_message) override; + void OnPromiseResolved(uint32_t promise_id) override; + void OnPromiseResolvedWithSession(uint32_t promise_id, + std::string session_id) override; + void OnSessionClosed(std::string session_id) override; + + void OnSessionKeysChange(std::string session_id, + std::vector key_id_array, + std::vector status_array, + bool has_additional_usable_key, + bool is_key_release) override; + void OnSessionExpirationUpdate(std::string session_id, + uint64_t expiration_time) override; + + void OnStorageProvisioned() override; + void OnStorageSaveInfo(std::vector ket_set_id, + std::string mime_type, + std::string session_id, + int32_t key_type) override; + void OnStorageLoadInfo(std::string session_id) override; + void OnStorageClearInfoForKeyRelease(std::string session_id) override; + void OnStorageClearInfoForLoadFail(std::string session_id) override; + + private: + const raw_ptr media_drm_bridge_; +}; + +} // namespace media + +#endif // MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_H_ diff --git a/media/base/ohos/ohos_media_drm_bridge_client.cc b/media/base/ohos/ohos_media_drm_bridge_client.cc new file mode 100644 index 0000000000000000000000000000000000000000..45a61f0ead3478a978c6d66cb7a07f568d63c629 --- /dev/null +++ b/media/base/ohos/ohos_media_drm_bridge_client.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/ohos/ohos_media_drm_bridge_client.h" + +#include "base/check.h" +#include "base/logging.h" + +namespace media { + +static OHOSMediaDrmBridgeClient* g_media_drm_bridge_client = nullptr; + +void SetMediaDrmBridgeClient(OHOSMediaDrmBridgeClient* media_client) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(!g_media_drm_bridge_client); + g_media_drm_bridge_client = media_client; +} + +OHOSMediaDrmBridgeClient* GetMediaDrmBridgeClient() { + LOG(INFO) << "[NEU][CDM]" << __func__; + return g_media_drm_bridge_client; +} + +OHOSMediaDrmBridgeClient::OHOSMediaDrmBridgeClient() {} + +OHOSMediaDrmBridgeClient::~OHOSMediaDrmBridgeClient() {} + +void OHOSMediaDrmBridgeClient::AddKeySystemUUIDMappings(KeySystemUuidMap* map) { +} + +media::OHOSMediaDrmBridgeDelegate* +OHOSMediaDrmBridgeClient::GetMediaDrmBridgeDelegate( + const std::vector& scheme_uuid) { + return nullptr; +} + +} // namespace media diff --git a/media/base/ohos/ohos_media_drm_bridge_client.h b/media/base/ohos/ohos_media_drm_bridge_client.h new file mode 100644 index 0000000000000000000000000000000000000000..ff0ecf4048da5dc1ea557e3d4d20fd98df36cd22 --- /dev/null +++ b/media/base/ohos/ohos_media_drm_bridge_client.h @@ -0,0 +1,53 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_CLIENT_H_ +#define MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_CLIENT_H_ + +#include + +#include +#include +#include +#include + +#include "media/base/media_export.h" + +namespace media { + +class OHOSMediaDrmBridgeClient; +class OHOSMediaDrmBridgeDelegate; + +MEDIA_EXPORT void SetMediaDrmBridgeClient( + OHOSMediaDrmBridgeClient* media_client); + +#if defined(IS_MEDIA_IMPL) +OHOSMediaDrmBridgeClient* GetMediaDrmBridgeClient(); +#endif + +using UUID = std::vector; + +class MEDIA_EXPORT OHOSMediaDrmBridgeClient { + public: + typedef std::unordered_map KeySystemUuidMap; + + OHOSMediaDrmBridgeClient(); + + OHOSMediaDrmBridgeClient(const OHOSMediaDrmBridgeClient&) = delete; + OHOSMediaDrmBridgeClient& operator=(const OHOSMediaDrmBridgeClient&) = delete; + + virtual ~OHOSMediaDrmBridgeClient(); + + virtual void AddKeySystemUUIDMappings(KeySystemUuidMap* map); + + virtual media::OHOSMediaDrmBridgeDelegate* GetMediaDrmBridgeDelegate( + const UUID& scheme_uuid); + + private: + friend class KeySystemManager; +}; + +} // namespace media + +#endif // MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_CLIENT_H_ diff --git a/media/base/ohos/ohos_media_drm_bridge_delegate.cc b/media/base/ohos/ohos_media_drm_bridge_delegate.cc new file mode 100644 index 0000000000000000000000000000000000000000..3b40b256f788794fd2d5ddc3c71e75bd602d24ed --- /dev/null +++ b/media/base/ohos/ohos_media_drm_bridge_delegate.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/ohos/ohos_media_drm_bridge_delegate.h" + +#include "base/check.h" +#include "base/logging.h" + +namespace media { + +OHOSMediaDrmBridgeDelegate::OHOSMediaDrmBridgeDelegate() {} + +OHOSMediaDrmBridgeDelegate::~OHOSMediaDrmBridgeDelegate() {} + +bool OHOSMediaDrmBridgeDelegate::OnCreateSession( + const EmeInitDataType init_data_type, + const std::vector& init_data, + std::vector* init_data_out, + std::vector* optional_parameters_out) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(init_data_out->empty()); + DCHECK(optional_parameters_out->empty()); + LOG(INFO) << "[NEU][CDM]" << __func__; + return true; +} + +} // namespace media diff --git a/media/base/ohos/ohos_media_drm_bridge_delegate.h b/media/base/ohos/ohos_media_drm_bridge_delegate.h new file mode 100644 index 0000000000000000000000000000000000000000..d046b39f6be359ff97c055f527401880b9038e2b --- /dev/null +++ b/media/base/ohos/ohos_media_drm_bridge_delegate.h @@ -0,0 +1,40 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_DELEGATE_H_ +#define MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_DELEGATE_H_ + +#include + +#include +#include + +#include "media/base/eme_constants.h" +#include "media/base/media_export.h" +#include "media/base/ohos/ohos_media_drm_bridge_client.h" + +namespace media { + +class MEDIA_EXPORT OHOSMediaDrmBridgeDelegate { + public: + OHOSMediaDrmBridgeDelegate(); + + OHOSMediaDrmBridgeDelegate(const OHOSMediaDrmBridgeDelegate&) = delete; + OHOSMediaDrmBridgeDelegate& operator=(const OHOSMediaDrmBridgeDelegate&) = + delete; + + virtual ~OHOSMediaDrmBridgeDelegate(); + + virtual const UUID GetUUID() const = 0; + + virtual bool OnCreateSession( + const EmeInitDataType init_data_type, + const std::vector& init_data, + std::vector* init_data_out, + std::vector* optional_parameters_out); +}; + +} // namespace media + +#endif // MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_BRIDGE_DELEGATE_H_ diff --git a/media/base/ohos/ohos_media_drm_bridge_factory.cc b/media/base/ohos/ohos_media_drm_bridge_factory.cc new file mode 100644 index 0000000000000000000000000000000000000000..e5f74dc953ece89d1c1702fa89fa8af81e4e8fb9 --- /dev/null +++ b/media/base/ohos/ohos_media_drm_bridge_factory.cc @@ -0,0 +1,132 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/ohos/ohos_media_drm_bridge_factory.h" + +#include "base/functional/bind.h" +#include "base/functional/callback_helpers.h" +#include "media/base/cdm_config.h" +#include "media/base/content_decryption_module.h" +#include "media/base/key_system_names.h" +#include "media/cdm/clear_key_cdm_common.h" +#include "third_party/widevine/cdm/widevine_cdm_common.h" + +namespace media { + +OHOSMediaDrmBridgeFactory::OHOSMediaDrmBridgeFactory( + CreateFetcherCB create_fetcher_cb, + CreateStorageCB create_storage_cb) + : create_fetcher_cb_(std::move(create_fetcher_cb)), + create_storage_cb_(std::move(create_storage_cb)) { + DCHECK(create_fetcher_cb_); + DCHECK(create_storage_cb_); +} + +OHOSMediaDrmBridgeFactory::~OHOSMediaDrmBridgeFactory() { + if (cdm_created_cb_) { + std::move(cdm_created_cb_).Run(nullptr, "CDM creation aborted"); + } +} + +void OHOSMediaDrmBridgeFactory::Create( + const CdmConfig& cdm_config, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb, + CdmCreatedCB cdm_created_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(OHOSMediaDrmBridge::IsKeySystemSupported(cdm_config.key_system)); + DCHECK(scheme_uuid_.empty()) << "This factory can only be used once."; + + scheme_uuid_ = OHOSMediaDrmBridge::GetUUID(cdm_config.key_system); + DCHECK(!scheme_uuid_.empty()); + + if (cdm_config.key_system == kWidevineKeySystem) { + LOG(INFO) << "[NEU][CDM]" << __func__; + security_level_ = cdm_config.use_hw_secure_codecs + ? OHOSMediaDrmBridge::SECURITY_LEVEL_1 + : OHOSMediaDrmBridge::SECURITY_LEVEL_3; + LOG(INFO) << "[NEU][CDM]" << __func__ + << " security_level_: " << security_level_; + } else if (media::IsExternalClearKey(cdm_config.key_system)) { + security_level_ = OHOSMediaDrmBridge::SECURITY_LEVEL_DEFAULT; + } else if (!cdm_config.use_hw_secure_codecs) { + auto error_message = + cdm_config.key_system + + " may require use_video_overlay_for_embedded_encrypted_video"; + NOTREACHED() << error_message; + std::move(cdm_created_cb).Run(nullptr, error_message); + return; + } + LOG(INFO) << "[NEU][CDM]" << __func__; + session_message_cb_ = session_message_cb; + session_closed_cb_ = session_closed_cb; + session_keys_change_cb_ = session_keys_change_cb; + session_expiration_update_cb_ = session_expiration_update_cb; + cdm_created_cb_ = std::move(cdm_created_cb); + LOG(INFO) << "[NEU][CDM]" << __func__; + storage_ = std::make_unique(); + + storage_->Initialize( + create_storage_cb_, + base::BindOnce(&OHOSMediaDrmBridgeFactory::OnStorageInitialized, + weak_factory_.GetWeakPtr())); +} + +void OHOSMediaDrmBridgeFactory::OnStorageInitialized(bool success) { + DCHECK(storage_); + DVLOG(2) << __func__ << ": success = " << success + << ", origin_id = " << storage_->origin_id(); + if (!success) { + std::move(cdm_created_cb_).Run(nullptr, "Cannot fetch origin ID"); + return; + } + + CreateMediaDrmBridge(storage_->origin_id()); +} + +void OHOSMediaDrmBridgeFactory::CreateMediaDrmBridge( + const std::string& origin_id) { + DCHECK(!ohos_media_drm_bridge_); + LOG(INFO) << "[NEU][CDM]" << __func__; + // Requires MediaCrypto so that it can be used by MediaCodec-based decoders. + const bool requires_media_crypto = true; + + ohos_media_drm_bridge_ = OHOSMediaDrmBridge::CreateInternal( + scheme_uuid_, origin_id, security_level_, requires_media_crypto, + std::move(storage_), create_fetcher_cb_, session_message_cb_, + session_closed_cb_, session_keys_change_cb_, + session_expiration_update_cb_); + LOG(INFO) << "[NEU][CDM]" << __func__; + if (!ohos_media_drm_bridge_) { + std::move(cdm_created_cb_) + .Run(nullptr, "OHOSMediaDrmBridge creation failed"); + LOG(INFO) << "[NEU][CDM]" << __func__; + return; + } + LOG(INFO) << "[NEU][CDM]" << __func__; + std::move(cdm_created_cb_).Run(ohos_media_drm_bridge_, ""); + + LOG(INFO) << "[NEU][CDM]" << __func__; + ohos_media_drm_bridge_->SetOHOSMediaCryptoReadyCB( + base::BindOnce(&OHOSMediaDrmBridgeFactory::OnOHOSMediaCryptoReady, + weak_factory_.GetWeakPtr())); +} + +void OHOSMediaDrmBridgeFactory::OnOHOSMediaCryptoReady( + void* session, + bool requires_secure_video_codec) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (!session) { + LOG(INFO) << "[NEU][CDM]" << __func__; + ohos_media_drm_bridge_ = nullptr; + std::move(cdm_created_cb_).Run(nullptr, "MediaCrypto not available"); + return; + } + std::move(cdm_created_cb_).Run(ohos_media_drm_bridge_, ""); + LOG(INFO) << "[NEU][CDM]" << __func__; +} + +} // namespace media diff --git a/media/base/ohos/ohos_media_drm_bridge_factory.h b/media/base/ohos/ohos_media_drm_bridge_factory.h new file mode 100644 index 0000000000000000000000000000000000000000..c0d33151ff978a09c01dd8b7a2f500c9536226f7 --- /dev/null +++ b/media/base/ohos/ohos_media_drm_bridge_factory.h @@ -0,0 +1,71 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_ANDROID_MEDIA_DRM_BRIDGE_FACTORY_H_ +#define MEDIA_BASE_ANDROID_MEDIA_DRM_BRIDGE_FACTORY_H_ + +#include + +#include +#include + +#include "base/memory/weak_ptr.h" +#include "media/base/cdm_factory.h" +#include "media/base/media_export.h" +#include "media/base/ohos/ohos_media_drm_bridge.h" +#include "media/base/ohos/ohos_media_drm_storage_bridge.h" +#include "media/base/provision_fetcher.h" + +namespace media { + +struct CdmConfig; + +class MEDIA_EXPORT OHOSMediaDrmBridgeFactory final : public CdmFactory { + public: + OHOSMediaDrmBridgeFactory(CreateFetcherCB create_fetcher_cb, + CreateStorageCB create_storage_cb); + + OHOSMediaDrmBridgeFactory(const OHOSMediaDrmBridgeFactory&) = delete; + OHOSMediaDrmBridgeFactory& operator=(const OHOSMediaDrmBridgeFactory&) = + delete; + + ~OHOSMediaDrmBridgeFactory() override; + + void Create(const CdmConfig& cdm_config, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb, + CdmCreatedCB cdm_created_cb) override; + + private: + void OnStorageInitialized(bool success); + void CreateMediaDrmBridge(const std::string& origin_id); + void OnOHOSMediaCryptoReady(void* session, bool requires_secure_video_codec); + + CreateFetcherCB create_fetcher_cb_; + CreateStorageCB create_storage_cb_; + + std::vector scheme_uuid_; + + OHOSMediaDrmBridge::SecurityLevel security_level_ = + OHOSMediaDrmBridge::SECURITY_LEVEL_DEFAULT; + + SessionMessageCB session_message_cb_; + SessionClosedCB session_closed_cb_; + SessionKeysChangeCB session_keys_change_cb_; + SessionExpirationUpdateCB session_expiration_update_cb_; + + using CdmCreatedOnceCB = base::OnceCallback; + CdmCreatedOnceCB cdm_created_cb_; + + std::unique_ptr storage_; + scoped_refptr ohos_media_drm_bridge_; + + base::WeakPtrFactory weak_factory_{this}; +}; + +} // namespace media + +#endif // MEDIA_BASE_ANDROID_MEDIA_DRM_BRIDGE_FACTORY_H_ diff --git a/media/base/ohos/ohos_media_drm_storage_bridge.cc b/media/base/ohos/ohos_media_drm_storage_bridge.cc new file mode 100644 index 0000000000000000000000000000000000000000..b0f8f8137af402889b112f777bb7870126d969ba --- /dev/null +++ b/media/base/ohos/ohos_media_drm_storage_bridge.cc @@ -0,0 +1,127 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/ohos/ohos_media_drm_storage_bridge.h" + +#include +#include +#include +#include + +#include "base/functional/bind.h" +#include "base/task/single_thread_task_runner.h" +#include "base/unguessable_token.h" +#include "media/base/media_drm_key_type.h" +#include "media/base/ohos/ohos_media_drm_bridge.h" + +namespace media { + +OHOSMediaDrmStorageBridge::OHOSMediaDrmStorageBridge() + : task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) {} + +OHOSMediaDrmStorageBridge::~OHOSMediaDrmStorageBridge() = default; + +void OHOSMediaDrmStorageBridge::Initialize( + const CreateStorageCB& create_storage_cb, + InitCB init_cb) { + DCHECK(create_storage_cb); + impl_ = create_storage_cb.Run(); + + impl_->Initialize(base::BindOnce(&OHOSMediaDrmStorageBridge::OnInitialized, + weak_factory_.GetWeakPtr(), + std::move(init_cb))); +} + +void OHOSMediaDrmStorageBridge::OnProvisioned( + MediaDrmStorage::ResultCB result_cb) { + DCHECK(impl_); + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&MediaDrmStorage::OnProvisioned, + impl_->AsWeakPtr(), std::move(result_cb))); +} + +void OHOSMediaDrmStorageBridge::OnLoadInfo(std::string session_id, + LoadResultCB load_result_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(impl_); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &MediaDrmStorage::LoadPersistentSession, impl_->AsWeakPtr(), + session_id, + base::BindOnce(&OHOSMediaDrmStorageBridge::OnSessionDataLoaded, + weak_factory_.GetWeakPtr(), std::move(load_result_cb), + session_id))); +} + +void OHOSMediaDrmStorageBridge::OnSaveInfo( + std::vector key_set_id, + std::string mime, + std::string session_id, + int32_t key_type, + MediaDrmStorage::ResultCB result_cb) { + DCHECK(impl_); + auto media_drm_key_type = static_cast(key_type); + DCHECK(media_drm_key_type == MediaDrmKeyType::OFFLINE || + media_drm_key_type == MediaDrmKeyType::RELEASE); + + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&MediaDrmStorage::SavePersistentSession, + impl_->AsWeakPtr(), session_id, + MediaDrmStorage::SessionData( + std::move(key_set_id), std::move(mime), + media_drm_key_type), + std::move(result_cb))); +} + +void OHOSMediaDrmStorageBridge::OnClearInfo( + std::string session_id, + MediaDrmStorage::ResultCB result_cb) { + DCHECK(impl_); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MediaDrmStorage::RemovePersistentSession, + impl_->AsWeakPtr(), session_id, std::move(result_cb))); +} + +void OHOSMediaDrmStorageBridge::OnInitialized( + InitCB init_cb, + bool success, + const MediaDrmStorage::MediaDrmOriginId& origin_id) { + if (!success) { + DCHECK(!origin_id); + std::move(init_cb).Run(false); + return; + } + + if (origin_id && origin_id.value()) { + origin_id_ = origin_id->ToString(); + } else { + DCHECK(origin_id_.empty()); + if (OHOSMediaDrmBridge::IsPerApplicationProvisioningSupported()) { + std::move(init_cb).Run(false); + return; + } + } + + std::move(init_cb).Run(true); +} + +void OHOSMediaDrmStorageBridge::OnSessionDataLoaded( + LoadResultCB load_result_cb, + const std::string& session_id, + std::unique_ptr session_data) { + LOG(INFO) << "[NEU][CDM]" << __func__; + if (!session_data) { + LOG(INFO) << "[NEU][CDM]" << __func__; + std::move(load_result_cb).Run(session_id, std::vector(), "", 0); + return; + } + LOG(INFO) << "[NEU][CDM]" << __func__; + std::move(load_result_cb) + .Run(session_id, session_data->key_set_id, session_data->mime_type, + static_cast(session_data->key_type)); +} + +} // namespace media diff --git a/media/base/ohos/ohos_media_drm_storage_bridge.h b/media/base/ohos/ohos_media_drm_storage_bridge.h new file mode 100644 index 0000000000000000000000000000000000000000..f3f882de88b362548618467a2f69502bfc049ea1 --- /dev/null +++ b/media/base/ohos/ohos_media_drm_storage_bridge.h @@ -0,0 +1,67 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_STORAGE_BRIDGE_H_ +#define MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_STORAGE_BRIDGE_H_ + +#include +#include + +#include "base/functional/callback.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "media/base/media_drm_storage.h" +#include "url/origin.h" + +namespace base { +class SingleThreadTaskRunner; +} // namespace base + +namespace media { + +class OHOSMediaDrmStorageBridge { + public: + using InitCB = base::OnceCallback; + using SaveResultCB = base::OnceCallback; + using LoadResultCB = base::OnceCallback< + void(std::string, std::vector, std::string, uint32_t)>; + + OHOSMediaDrmStorageBridge(); + + OHOSMediaDrmStorageBridge(const OHOSMediaDrmStorageBridge&) = delete; + OHOSMediaDrmStorageBridge& operator=(const OHOSMediaDrmStorageBridge&) = + delete; + + ~OHOSMediaDrmStorageBridge(); + + void Initialize(const CreateStorageCB& create_storage_cb, InitCB init_cb); + + const std::string& origin_id() const { return origin_id_; } + + void OnProvisioned(MediaDrmStorage::ResultCB result_cb); + void OnLoadInfo(std::string sessionId, LoadResultCB load_result_cb); + void OnSaveInfo(std::vector ketSetId, + std::string mimeType, + std::string sessionId, + int32_t keyType, + MediaDrmStorage::ResultCB result_cb); + void OnClearInfo(std::string sessionId, MediaDrmStorage::ResultCB resultCB); + + private: + void OnInitialized(InitCB init_cb, + bool success, + const MediaDrmStorage::MediaDrmOriginId& origin_id); + void OnSessionDataLoaded( + LoadResultCB load_result_cb, + const std::string& session_id, + std::unique_ptr session_data); + + std::unique_ptr impl_; + std::string origin_id_; + scoped_refptr task_runner_; + base::WeakPtrFactory weak_factory_{this}; +}; + +} // namespace media +#endif // MEDIA_BASE_OHOS_OHOS_MEDIA_DRM_STORAGE_BRIDGE_H_ diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index 3f7284e3430e676e029ed2cfc96294ba9a490d77..554d403b1b31fa5a36397a46a4a47046d8547512 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc @@ -284,6 +284,7 @@ void PipelineImpl::RendererWrapper::Start( Demuxer* demuxer, std::unique_ptr default_renderer, base::WeakPtr weak_pipeline) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); DCHECK(state_ == kCreated || state_ == kStopped) << "Received start in unexpected state: " << state_; @@ -327,6 +328,7 @@ void PipelineImpl::RendererWrapper::Start( std::move(fns), base::BindOnce(&RendererWrapper::CompleteSeek, weak_factory_.GetWeakPtr(), base::TimeDelta())); + LOG(INFO) << "[NEU][CDM]" << __func__; } void PipelineImpl::RendererWrapper::Stop() { @@ -1073,12 +1075,13 @@ void PipelineImpl::RendererWrapper::CompleteSuspend(PipelineStatus status) { void PipelineImpl::RendererWrapper::InitializeDemuxer( PipelineStatusCallback done_cb) { DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - + LOG(INFO) << "[NEU][CDM]" << __func__; demuxer_->Initialize(this, std::move(done_cb)); } void PipelineImpl::RendererWrapper::CreateRenderer( PipelineStatusCallback done_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); DCHECK(state_ == kStarting || state_ == kResuming); @@ -1096,6 +1099,7 @@ void PipelineImpl::RendererWrapper::CreateRenderer( void PipelineImpl::RendererWrapper::OnRendererCreated( PipelineStatusCallback done_cb, std::unique_ptr renderer) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__ << ": renderer=" << renderer.get(); DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); @@ -1117,7 +1121,7 @@ void PipelineImpl::RendererWrapper::InitializeRenderer( PipelineStatusCallback done_cb) { DVLOG(1) << __func__; DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - + LOG(INFO) << "[NEU][CDM]" << __func__; switch (demuxer_->GetType()) { case MediaResource::Type::STREAM: if (demuxer_->GetAllStreams().empty()) { @@ -1169,7 +1173,7 @@ void PipelineImpl::RendererWrapper::DestroyRenderer() { void PipelineImpl::RendererWrapper::ReportMetadata(StartType start_type) { DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - + LOG(INFO) << "[NEU][CDM]" << __func__; PipelineMetadata metadata; std::vector streams; @@ -1279,6 +1283,7 @@ void PipelineImpl::Start(StartType start_type, Demuxer* demuxer, Client* client, PipelineStatusCallback seek_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__ << ": start_type=" << static_cast(start_type); DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(demuxer); @@ -1307,6 +1312,7 @@ void PipelineImpl::Start(StartType start_type, base::Unretained(renderer_wrapper_.get()), start_type, demuxer, std::move(default_renderer), weak_factory_.GetWeakPtr())); + LOG(INFO) << "[NEU][CDM]" << __func__; } void PipelineImpl::Stop() { diff --git a/media/cdm/cdm_adapter.cc b/media/cdm/cdm_adapter.cc index 69f03e61c6fd6b603cd448912dd55e1a4dda68e7..f9393dc10c6e8eff31f902ca4e33da7fc7f5a012 100644 --- a/media/cdm/cdm_adapter.cc +++ b/media/cdm/cdm_adapter.cc @@ -332,6 +332,7 @@ void CdmAdapter::CreateSessionAndGenerateRequest( EmeInitDataType init_data_type, const std::vector& init_data, std::unique_ptr promise) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); TRACE_EVENT0("media", "CdmAdapter::CreateSessionAndGenerateRequest"); @@ -342,6 +343,7 @@ void CdmAdapter::CreateSessionAndGenerateRequest( cdm_->CreateSessionAndGenerateRequest( promise_id, ToCdmSessionType(session_type), ToCdmInitDataType(init_data_type), init_data.data(), init_data.size()); + LOG(INFO) << "[NEU][CDM]" << __func__; } void CdmAdapter::LoadSession(CdmSessionType session_type, @@ -362,6 +364,7 @@ void CdmAdapter::LoadSession(CdmSessionType session_type, void CdmAdapter::UpdateSession(const std::string& session_id, const std::vector& response, std::unique_ptr promise) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(!session_id.empty()); DCHECK(!response.empty()); @@ -374,6 +377,7 @@ void CdmAdapter::UpdateSession(const std::string& session_id, cdm_->UpdateSession(promise_id, session_id.data(), session_id.size(), response.data(), response.size()); + LOG(INFO) << "[NEU][CDM]" << __func__; } void CdmAdapter::CloseSession(const std::string& session_id, diff --git a/media/cdm/cdm_wrapper.h b/media/cdm/cdm_wrapper.h index a84bc3d2efa7d1f96ea679d298a760a8657fde8c..126b93306d47d9d5984315a339cf870ec0ee024b 100644 --- a/media/cdm/cdm_wrapper.h +++ b/media/cdm/cdm_wrapper.h @@ -204,8 +204,10 @@ class CdmWrapperImpl : public CdmWrapper { cdm::InitDataType init_data_type, const uint8_t* init_data, uint32_t init_data_size) override { + LOG(INFO) << "[NEU][CDM]" << __func__; cdm_->CreateSessionAndGenerateRequest( promise_id, session_type, init_data_type, init_data, init_data_size); + LOG(INFO) << "[NEU][CDM]" << __func__; } void LoadSession(uint32_t promise_id, @@ -220,8 +222,10 @@ class CdmWrapperImpl : public CdmWrapper { uint32_t session_id_size, const uint8_t* response, uint32_t response_size) override { + LOG(INFO) << "[NEU][CDM]" << __func__; cdm_->UpdateSession(promise_id, session_id, session_id_size, response, response_size); + LOG(INFO) << "[NEU][CDM]" << __func__; } void CloseSession(uint32_t promise_id, diff --git a/media/cdm/cenc_utils.cc b/media/cdm/cenc_utils.cc index c680ce5fdfbd36db9d5923633618fc732e606909..10c1d45696822fd3fb5355d55c6904e45e296f9b 100644 --- a/media/cdm/cenc_utils.cc +++ b/media/cdm/cenc_utils.cc @@ -109,13 +109,14 @@ bool GetKeyIdsForCommonSystemId(const std::vector& pssh_boxes, bool GetPsshData(const std::vector& input, const std::vector& system_id, std::vector* pssh_data) { + LOG(INFO) << "[NEU][CDM]" << __func__; if (input.empty()) return false; - + LOG(INFO) << "[NEU][CDM]" << __func__; std::vector children; if (!ReadAllPsshBoxes(input, &children)) return false; - + LOG(INFO) << "[NEU][CDM]" << __func__; // Check all children for an appropriate 'pssh' box, returning |data| from // the first one found. for (const auto& child : children) { @@ -124,7 +125,7 @@ bool GetPsshData(const std::vector& input, return true; } } - + LOG(INFO) << "[NEU][CDM]" << __func__; // No matching 'pssh' box found. return false; } diff --git a/media/cdm/default_cdm_factory.cc b/media/cdm/default_cdm_factory.cc index 0b344810e77a75216e988c9af40ede47496892e1..ccef7f9dc187394caaca257525a777ce2c75ef32 100644 --- a/media/cdm/default_cdm_factory.cc +++ b/media/cdm/default_cdm_factory.cc @@ -44,7 +44,7 @@ void DefaultCdmFactory::Create( "Unsupported key system.")); return; } - + LOG(INFO) << "[NEU][CDM]" << __func__; auto cdm = base::MakeRefCounted( session_message_cb, session_closed_cb, session_keys_change_cb, session_expiration_update_cb); diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc index 1a44c0bca2e50c6b9c5e200c7340c5935de27f2b..ad1d5db25f5a17d68b5d2f6aa98b5a4f71369b8b 100644 --- a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc +++ b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc @@ -187,7 +187,7 @@ class VideoDecoderAdapter final : public CdmVideoDecoder { auto clear_config = ToClearMediaVideoDecoderConfig(config); DVLOG(1) << __func__ << ": " << clear_config.AsHumanReadableString(); DCHECK(!last_init_result_.has_value()); - + LOG(INFO) << "[NEU][CDM]" << __func__; // Initialize |video_decoder_| and wait for completion. base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); video_decoder_->Initialize( @@ -203,7 +203,7 @@ class VideoDecoderAdapter final : public CdmVideoDecoder { auto result = std::move(last_init_result_.value()); last_init_result_.reset(); - + LOG(INFO) << "[NEU][CDM]" << __func__; return result; } @@ -269,7 +269,7 @@ class VideoDecoderAdapter final : public CdmVideoDecoder { // Do not queue EOS frames, which is not needed. if (video_frame->metadata().end_of_stream) return; - + LOG(INFO) << "[NEU][CDM]" << __func__; decoded_video_frames_.push(std::move(video_frame)); } @@ -305,6 +305,7 @@ class VideoDecoderAdapter final : public CdmVideoDecoder { std::unique_ptr CreateVideoDecoder( CdmHostProxy* cdm_host_proxy, const cdm::VideoDecoderConfig_3& config) { + LOG(INFO) << "[NEU][CDM]" << __func__; SetupGlobalEnvironmentIfNeeded(); static base::NoDestructor null_media_log; @@ -327,7 +328,7 @@ std::unique_ptr CreateVideoDecoder( if (!video_decoder) return nullptr; - + LOG(INFO) << "[NEU][CDM]" << __func__; return std::make_unique(cdm_host_proxy, std::move(video_decoder)); } diff --git a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc index 4d6306c598bccdb849344ce3311ab57f9775534c..eac3aeaa6d62c20339170f5cc1f1fd899a3065dd 100644 --- a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc +++ b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc @@ -356,7 +356,7 @@ void ClearKeyCdm::CreateSessionAndGenerateRequest( const uint8_t* init_data, uint32_t init_data_size) { DVLOG(1) << __func__; - + LOG(INFO) << "[NEU][CDM]" << __func__; if (session_type != cdm::kTemporary && !allow_persistent_state_) { OnPromiseFailed(promise_id, CdmPromise::Exception::INVALID_STATE_ERROR, 0, "Persistent state not allowed."); @@ -387,6 +387,7 @@ void ClearKeyCdm::CreateSessionAndGenerateRequest( } else if (key_system_ == kExternalClearKeyStorageIdTestKeySystem) { StartStorageIdTest(); } + LOG(INFO) << "[NEU][CDM]" << __func__; } void ClearKeyCdm::LoadSession(uint32_t promise_id, @@ -412,6 +413,7 @@ void ClearKeyCdm::UpdateSession(uint32_t promise_id, uint32_t session_id_length, const uint8_t* response, uint32_t response_size) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; std::string web_session_str(session_id, session_id_length); std::vector response_vector(response, response + response_size); @@ -423,6 +425,7 @@ void ClearKeyCdm::UpdateSession(uint32_t promise_id, promise_id)); cdm_->UpdateSession(session_id, response_vector, std::move(promise)); + LOG(INFO) << "[NEU][CDM]" << __func__; } void ClearKeyCdm::OnUpdateSuccess(uint32_t promise_id, @@ -544,6 +547,7 @@ static void CopyDecryptResults(Decryptor::Status* status_copy, cdm::Status ClearKeyCdm::Decrypt(const cdm::InputBuffer_2& encrypted_buffer, cdm::DecryptedBlock* decrypted_block) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; DCHECK(encrypted_buffer.data); @@ -560,7 +564,7 @@ cdm::Status ClearKeyCdm::Decrypt(const cdm::InputBuffer_2& encrypted_buffer, buffer->data(), buffer->data_size()); decrypted_block->DecryptedBuffer()->SetSize(buffer->data_size()); decrypted_block->SetTimestamp(buffer->timestamp().InMicroseconds()); - + LOG(INFO) << "[NEU][CDM]" << __func__; return cdm::kSuccess; } @@ -854,7 +858,7 @@ void ClearKeyCdm::OnSessionKeysChange(const std::string& session_id, bool has_additional_usable_key, CdmKeysInfo keys_info) { DVLOG(1) << __func__ << ": size = " << keys_info.size(); - + LOG(INFO) << "[NEU][CDM]" << __func__; // Crash if the special key ID "crash" is present. const std::vector kCrashKeyId{'c', 'r', 'a', 's', 'h'}; for (const auto& key_info : keys_info) { @@ -867,6 +871,7 @@ void ClearKeyCdm::OnSessionKeysChange(const std::string& session_id, cdm_host_proxy_->OnSessionKeysChange(session_id.data(), session_id.length(), has_additional_usable_key, keys_vector.data(), keys_vector.size()); + LOG(INFO) << "[NEU][CDM]" << __func__; } void ClearKeyCdm::OnSessionClosed(const std::string& session_id, diff --git a/media/cdm/library_cdm/clear_key_cdm/clear_key_persistent_session_cdm.cc b/media/cdm/library_cdm/clear_key_cdm/clear_key_persistent_session_cdm.cc index 844b35685f03e131dc5236a1d8e2482064840af2..47fd34fedc413bc4bf8ff8565f719d25cfd13e4f 100644 --- a/media/cdm/library_cdm/clear_key_cdm/clear_key_persistent_session_cdm.cc +++ b/media/cdm/library_cdm/clear_key_cdm/clear_key_persistent_session_cdm.cc @@ -103,6 +103,7 @@ ClearKeyPersistentSessionCdm::ClearKeyPersistentSessionCdm( : cdm_host_proxy_(cdm_host_proxy), session_message_cb_(session_message_cb), session_closed_cb_(session_closed_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; cdm_ = base::MakeRefCounted( base::BindRepeating(&ClearKeyPersistentSessionCdm::OnSessionMessage, weak_factory_.GetWeakPtr()), @@ -124,6 +125,7 @@ void ClearKeyPersistentSessionCdm::CreateSessionAndGenerateRequest( EmeInitDataType init_data_type, const std::vector& init_data, std::unique_ptr promise) { + LOG(INFO) << "[NEU][CDM]" << __func__; std::unique_ptr new_promise; if (session_type == CdmSessionType::kTemporary) { new_promise = std::move(promise); @@ -137,6 +139,7 @@ void ClearKeyPersistentSessionCdm::CreateSessionAndGenerateRequest( } cdm_->CreateSessionAndGenerateRequest(session_type, init_data_type, init_data, std::move(new_promise)); + LOG(INFO) << "[NEU][CDM]" << __func__; } void ClearKeyPersistentSessionCdm::LoadSession( @@ -222,11 +225,12 @@ void ClearKeyPersistentSessionCdm::UpdateSession( const std::vector& response, std::unique_ptr promise) { CHECK(!response.empty()); - + LOG(INFO) << "[NEU][CDM]" << __func__; auto it = persistent_sessions_.find(session_id); if (it == persistent_sessions_.end()) { // Not a persistent session, so simply pass the request on. cdm_->UpdateSession(session_id, response, std::move(promise)); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } diff --git a/media/filters/decoder_selector.cc b/media/filters/decoder_selector.cc index 814c5ae4026fcd5f8b9f8cbbd6a44fbc3854c8af..b33a34fe52f471fae0455f9197c1c015d2e9770f 100644 --- a/media/filters/decoder_selector.cc +++ b/media/filters/decoder_selector.cc @@ -84,12 +84,14 @@ DecoderPriority PreferNonPlatformDecoders(const VideoDecoderConfig& config, // Prefer software decoders over hardware decoders. This is useful to force // software fallback for WebRTC, but still use hardware if there's no software // implementation to choose. + LOG(INFO) << "[NEU][CDM]" << __func__; return decoder.IsPlatformDecoder() ? DecoderPriority::kDeprioritized : DecoderPriority::kNormal; } DecoderPriority UnifiedDecoderPriority(const VideoDecoderConfig& config, const VideoDecoder& decoder) { + LOG(INFO) << "[NEU][CDM]" << __func__; if (config.is_rtc() || base::FeatureList::IsEnabled(kResolutionBasedDecoderPriority)) { return ResolutionBasedDecoderPriority(config, decoder); @@ -101,6 +103,7 @@ DecoderPriority UnifiedDecoderPriority(const VideoDecoderConfig& config, template DecoderPriority SkipNonPlatformDecoders(const ConfigT& config, const DecoderT& decoder) { + LOG(INFO) << "[NEU][CDM]" << __func__; if (SkipDecoderForRTC(config, decoder)) return DecoderPriority::kSkipped; @@ -111,14 +114,19 @@ DecoderPriority SkipNonPlatformDecoders(const ConfigT& config, void SetDefaultDecoderPriorityCB( VideoDecoderSelector::DecoderPriorityCB* out, const DecoderStreamTraits* traits) { + LOG(INFO) << "[NEU][CDM]" << __func__; if (base::FeatureList::IsEnabled(kForceHardwareVideoDecoders)) { + LOG(INFO) << "[NEU][CDM]" << __func__; *out = base::BindRepeating( SkipNonPlatformDecoders); } else if (traits->GetPreferNonPlatformDecoders()) { + LOG(INFO) << "[NEU][CDM]" << __func__; *out = base::BindRepeating(PreferNonPlatformDecoders); } else { + LOG(INFO) << "[NEU][CDM]" << __func__; *out = base::BindRepeating(UnifiedDecoderPriority); } + LOG(INFO) << "[NEU][CDM]" << __func__; } void SetDefaultDecoderPriorityCB( @@ -195,11 +203,13 @@ void DecoderSelector::SelectDecoderInternal( ReturnSelectionError(DecoderStatus::Codes::kUnsupportedConfig); return; } - + LOG(INFO) << "[NEU][CDM]" << __func__; if (needs_new_decoders) { decode_failure_reinit_cause_ = absl::nullopt; CreateDecoders(); + LOG(INFO) << "[NEU][CDM]" << __func__; } + LOG(INFO) << "[NEU][CDM]" << __func__; GetAndInitializeNextDecoder(); } @@ -208,8 +218,10 @@ template void DecoderSelector::BeginDecoderSelection( SelectDecoderCB select_decoder_cb, typename Decoder::OutputCB output_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; SelectDecoderInternal(std::move(select_decoder_cb), std::move(output_cb), /*needs_new_decoders = */ true); + LOG(INFO) << "[NEU][CDM]" << __func__; } template @@ -258,10 +270,12 @@ void DecoderSelector::CreateDecoders() { // any decoders added via `PrependDecoder()` are not overwritten and retain // priority (even if they are ultimately de-ranked by // `FilterAndSortAvailableDecoders()`) + LOG(INFO) << "[NEU][CDM]" << __func__; auto new_decoders = create_decoders_cb_.Run(); std::move(new_decoders.begin(), new_decoders.end(), std::inserter(decoders_, decoders_.end())); FilterAndSortAvailableDecoders(); + LOG(INFO) << "[NEU][CDM]" << __func__; } template @@ -294,16 +308,19 @@ void DecoderSelector::GetAndInitializeNextDecoder() { DVLOG(2) << __func__ << ": initializing " << decoder_->GetDecoderType(); const bool is_live = stream_->liveness() == StreamLiveness::kLive; + LOG(INFO) << "[NEU][CDM]" << __func__; traits_->InitializeDecoder( decoder_.get(), config_, is_live, cdm_context_, base::BindOnce(&DecoderSelector::OnDecoderInitializeDone, weak_this_factory_.GetWeakPtr()), output_cb_, waiting_cb_); + LOG(INFO) << "[NEU][CDM]" << __func__; } template void DecoderSelector::OnDecoderInitializeDone( DecoderStatus status) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(decoder_); #if defined(OHOS_MEDIA) LOG(WARNING) << "OhMedia::OnDecoderInitializeDone" @@ -325,10 +342,12 @@ void DecoderSelector::OnDecoderInitializeDone( // Try the next decoder on the list. decoder_ = nullptr; GetAndInitializeNextDecoder(); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } RunSelectDecoderCB(std::move(decoder_)); + LOG(INFO) << "[NEU][CDM]" << __func__; } template @@ -352,12 +371,13 @@ void DecoderSelector::InitializeDecryptingDemuxerStream() { decrypting_demuxer_stream_ = std::make_unique( task_runner_, media_log_, waiting_cb_); - + LOG(INFO) << "[NEU][CDM]" << __func__; decrypting_demuxer_stream_->Initialize( stream_, cdm_context_, base::BindOnce( &DecoderSelector::OnDecryptingDemuxerStreamInitializeDone, weak_this_factory_.GetWeakPtr())); + LOG(INFO) << "[NEU][CDM]" << __func__; } template @@ -365,7 +385,7 @@ void DecoderSelector::OnDecryptingDemuxerStreamInitializeDone( PipelineStatus status) { DVLOG(2) << __func__ << ": status=" << status; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - + LOG(INFO) << "[NEU][CDM]" << __func__; if (status != PIPELINE_OK) { // Since we already tried every potential decoder without DDS, give up. ReturnSelectionError( @@ -385,6 +405,7 @@ void DecoderSelector::OnDecryptingDemuxerStreamInitializeDone( // Try decoder selection again now that DDS is being used. CreateDecoders(); GetAndInitializeNextDecoder(); + LOG(INFO) << "[NEU][CDM]" << __func__; } template diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc index 4055fa3596cccfb7013b8c6bb2c871ce5c46eaf6..57cb0b8cef553456ea191e1ce84ac4797fbd5fef 100644 --- a/media/filters/decoder_stream.cc +++ b/media/filters/decoder_stream.cc @@ -170,11 +170,14 @@ void DecoderStream::Initialize(DemuxerStream* stream, std::move(waiting_cb)); state_ = STATE_INITIALIZING; + LOG(INFO) << "[NEU][CDM]" << __func__; BeginDecoderSelection(); + LOG(INFO) << "[NEU][CDM]" << __func__; } template void DecoderStream::Read(ReadCB read_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; FUNCTION_DVLOG(3); DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) @@ -211,6 +214,7 @@ void DecoderStream::Read(ReadCB read_cb) { if (state_ == STATE_NORMAL && CanDecodeMore()) ReadFromDemuxerStream(); + LOG(INFO) << "[NEU][CDM]" << __func__; } template @@ -339,28 +343,33 @@ void DecoderStream::SkipPrepareUntil( template void DecoderStream::BeginDecoderSelection() { + LOG(INFO) << "[NEU][CDM]" << __func__; decoder_selector_.BeginDecoderSelection( base::BindOnce(&DecoderStream::OnDecoderSelected, weak_factory_.GetWeakPtr()), base::BindRepeating(&DecoderStream::OnDecodeOutputReady, fallback_weak_factory_.GetWeakPtr())); + LOG(INFO) << "[NEU][CDM]" << __func__; } template void DecoderStream::ResumeDecoderSelection( DecoderStatus&& reinit_cause) { + LOG(INFO) << "[NEU][CDM]" << __func__; decoder_selector_.ResumeDecoderSelection( base::BindOnce(&DecoderStream::OnDecoderSelected, weak_factory_.GetWeakPtr()), base::BindRepeating(&DecoderStream::OnDecodeOutputReady, fallback_weak_factory_.GetWeakPtr()), std::move(reinit_cause)); + LOG(INFO) << "[NEU][CDM]" << __func__; } template void DecoderStream::OnDecoderSelected( DecoderStatus::Or> decoder_or_error, std::unique_ptr decrypting_demuxer_stream) { + LOG(INFO) << "[NEU][CDM]" << __func__; FUNCTION_DVLOG(1) << ": " << (decoder_or_error.has_value() ? GetDecoderName(decoder_or_error->GetDecoderType()) @@ -456,18 +465,22 @@ void DecoderStream::OnDecoderSelected( if (StreamTraits::NeedsBitstreamConversion(decoder_.get())) stream_->EnableBitstreamConverter(); std::move(init_cb_).Run(true); + LOG(INFO) << "[NEU][CDM]" << __func__; } template void DecoderStream::SatisfyRead(ReadResult result) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(read_cb_); TRACE_EVENT_ASYNC_END1("media", GetReadTraceString(), this, "status", GetStatusString(result.code())); std::move(read_cb_).Run(std::move(result)); + LOG(INFO) << "[NEU][CDM]" << __func__; } template void DecoderStream::Decode(scoped_refptr buffer) { + LOG(INFO) << "[NEU][CDM]" << __func__; FUNCTION_DVLOG(3); // We don't know if the decoder will error out on first decode yet. Save the @@ -501,6 +514,7 @@ void DecoderStream::Decode(scoped_refptr buffer) { } DecodeInternal(std::move(buffer)); + LOG(INFO) << "[NEU][CDM]" << __func__; } template @@ -511,7 +525,7 @@ void DecoderStream::DecodeInternal( DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); DCHECK(!reset_cb_); DCHECK(buffer); - + LOG(INFO) << "[NEU][CDM]" << __func__; std::unique_ptr trace_event; if (MediaTraceIsEnabled()) { // Because multiple Decode() calls may be in flight, each call needs a @@ -537,6 +551,7 @@ void DecoderStream::DecodeInternal( base::BindOnce(&DecoderStream::OnDecodeDone, fallback_weak_factory_.GetWeakPtr(), buffer_size, decoding_eos_, std::move(trace_event))); + LOG(INFO) << "[NEU][CDM]" << __func__; } template @@ -652,6 +667,7 @@ void DecoderStream::OnDecodeDone( template void DecoderStream::OnDecodeOutputReady( scoped_refptr output) { + LOG(INFO) << "[NEU][CDM]" << __func__; FUNCTION_DVLOG(3) << ": " << output->timestamp().InMilliseconds() << " ms"; DCHECK(output); DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || @@ -701,10 +717,12 @@ void DecoderStream::OnDecodeOutputReady( // Store decoded output. ready_outputs_.push_back(std::move(output)); + LOG(INFO) << "[NEU][CDM]" << __func__; } template void DecoderStream::ReadFromDemuxerStream() { + LOG(INFO) << "[NEU][CDM]" << __func__; FUNCTION_DVLOG(3); DCHECK_EQ(state_, STATE_NORMAL); DCHECK(CanDecodeMore()); @@ -717,6 +735,7 @@ void DecoderStream::ReadFromDemuxerStream() { // Decode the buffer without re-appending it to |pending_buffers_|. DecodeInternal(std::move(buffer)); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } @@ -890,10 +909,12 @@ void DecoderStream::OnBufferReady( // Read more data if the decoder supports multiple parallel decoding requests. if (CanDecodeMore()) ReadFromDemuxerStream(); + LOG(INFO) << "[NEU][CDM]" << __func__; } template void DecoderStream::ReinitializeDecoder() { + LOG(INFO) << "[NEU][CDM]" << __func__; FUNCTION_DVLOG(2); DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK_EQ(state_, STATE_FLUSHING_DECODER); @@ -902,6 +923,7 @@ void DecoderStream::ReinitializeDecoder() { state_ = STATE_REINITIALIZING_DECODER; decoder_selector_.PrependDecoder(std::move(decoder_)); BeginDecoderSelection(); + LOG(INFO) << "[NEU][CDM]" << __func__; } template diff --git a/media/filters/decoder_stream_traits.cc b/media/filters/decoder_stream_traits.cc index c178bd5c412c35a2d78ba0af25ef19798191bde1..f717bba701a224e40a7db825f0e75716f987b8ff 100644 --- a/media/filters/decoder_stream_traits.cc +++ b/media/filters/decoder_stream_traits.cc @@ -215,6 +215,7 @@ void DecoderStreamTraits::InitializeDecoder( InitCB init_cb, const OutputCB& output_cb, const WaitingCB& waiting_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(config.IsValidConfig()); stats_.video_pipeline_info.decoder_type = VideoDecoderType::kUnknown; transform_ = config.video_transformation(); @@ -226,6 +227,7 @@ void DecoderStreamTraits::InitializeDecoder( &DecoderStreamTraits::OnDecoderInitialized, weak_this_, base::Unretained(decoder), std::move(init_cb)), output_cb, waiting_cb); + LOG(INFO) << "[NEU][CDM]" << __func__; } void DecoderStreamTraits::OnDecoderInitialized( diff --git a/media/filters/decrypting_demuxer_stream.cc b/media/filters/decrypting_demuxer_stream.cc index d77d12b3274f9c0c512ecfd4758710fc825cb4da..3c20a6732ff547d0ebe8cf93396e7b3a6491095f 100644 --- a/media/filters/decrypting_demuxer_stream.cc +++ b/media/filters/decrypting_demuxer_stream.cc @@ -73,6 +73,7 @@ void DecryptingDemuxerStream::Initialize(DemuxerStream* stream, } void DecryptingDemuxerStream::Read(uint32_t count, ReadCB read_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(3) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(state_, kIdle) << state_; @@ -86,6 +87,7 @@ void DecryptingDemuxerStream::Read(uint32_t count, ReadCB read_cb) { 1, base::BindOnce(&DecryptingDemuxerStream::OnBuffersReadFromDemuxerStream, weak_factory_.GetWeakPtr())); + LOG(INFO) << "[NEU][CDM]" << __func__; } void DecryptingDemuxerStream::Reset(base::OnceClosure closure) { @@ -180,15 +182,18 @@ DecryptingDemuxerStream::~DecryptingDemuxerStream() { void DecryptingDemuxerStream::OnBuffersReadFromDemuxerStream( DemuxerStream::Status status, DemuxerStream::DecoderBufferVector buffers) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK_LE(buffers.size(), 1u) << "DecryptingDemuxerStream only reads a single-buffer."; OnBufferReadFromDemuxerStream( status, buffers.empty() ? nullptr : std::move(buffers[0])); + LOG(INFO) << "[NEU][CDM]" << __func__; } void DecryptingDemuxerStream::OnBufferReadFromDemuxerStream( DemuxerStream::Status status, scoped_refptr buffer) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(3) << __func__ << ": status = " << status; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(state_, kPendingDemuxerRead) << state_; @@ -253,9 +258,11 @@ void DecryptingDemuxerStream::OnBufferReadFromDemuxerStream( pending_buffer_to_decrypt_ = std::move(buffer); state_ = kPendingDecrypt; DecryptPendingBuffer(); + LOG(INFO) << "[NEU][CDM]" << __func__; } void DecryptingDemuxerStream::DecryptPendingBuffer() { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(state_, kPendingDecrypt) << state_; DCHECK(!pending_buffer_to_decrypt_->end_of_stream()); @@ -276,11 +283,15 @@ void DecryptingDemuxerStream::DecryptPendingBuffer() { base::BindPostTaskToCurrentDefault(base::BindOnce( &DecryptingDemuxerStream::OnBufferDecrypted, weak_factory_.GetWeakPtr()))); + LOG(INFO) << "[NEU][CDM]" << __func__; } void DecryptingDemuxerStream::OnBufferDecrypted( Decryptor::Status status, scoped_refptr decrypted_buffer) { + + LOG(INFO) << "[NEU][CDM]" << __func__; + DVLOG(3) << __func__ << " - status: " << status; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(state_, kPendingDecrypt) << state_; @@ -347,11 +358,13 @@ void DecryptingDemuxerStream::OnBufferDecrypted( pending_buffer_to_decrypt_ = nullptr; state_ = kIdle; std::move(read_cb_).Run(kOk, {std::move(decrypted_buffer)}); + + LOG(INFO) << "[NEU][CDM]" << __func__; } void DecryptingDemuxerStream::OnCdmContextEvent(CdmContext::Event event) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - + LOG(INFO) << "[NEU][CDM]" << __func__; if (event != CdmContext::Event::kHasAdditionalUsableKey) return; @@ -369,6 +382,7 @@ void DecryptingDemuxerStream::OnCdmContextEvent(CdmContext::Event event) { << GetDisplayName() << ": key was added, resuming decrypt"; state_ = kPendingDecrypt; DecryptPendingBuffer(); + LOG(INFO) << "[NEU][CDM]" << __func__; } void DecryptingDemuxerStream::DoReset() { diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc index bc08240fa38d93088162eb8fe04f588c397d25d2..2556e6fb75ee3193e52e9897e6a324e3e9b6247c 100644 --- a/media/filters/decrypting_video_decoder.cc +++ b/media/filters/decrypting_video_decoder.cc @@ -102,6 +102,7 @@ bool DecryptingVideoDecoder::SupportsDecryption() const { void DecryptingVideoDecoder::Decode(scoped_refptr buffer, DecodeCB decode_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(3) << "Decode()"; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(state_ == kIdle || state_ == kDecodeFinished || state_ == kError) diff --git a/media/filters/demuxer_manager.cc b/media/filters/demuxer_manager.cc index 852c18a54c48aca300bd58e0f7fcc63dd64e4fbf..d92707ed8b7d64b1114b180a172be9d238fc75a0 100644 --- a/media/filters/demuxer_manager.cc +++ b/media/filters/demuxer_manager.cc @@ -410,6 +410,7 @@ PipelineStatus DemuxerManager::CreateDemuxer( uint32_t media_source_type, #endif // OHOS_CUSTOM_VIDEO_PLAYER DemuxerManager::DemuxerCreatedCB on_demuxer_created) { + LOG(INFO) << "[NEU][CDM]" << __func__; // TODO(crbug/1377053) return a better error if (!client_) { return DEMUXER_ERROR_COULD_NOT_OPEN; @@ -453,16 +454,19 @@ PipelineStatus DemuxerManager::CreateDemuxer( bool is_static = true; if (demuxer_override_) { + LOG(INFO) << "[NEU][CDM]" << __func__; // TODO(https://crbug.com/1076267): Should everything else after this block // run in the demuxer override case? SetDemuxer(std::move(demuxer_override_)); } else if (!load_media_source) { + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(ENABLE_FFMPEG) SetDemuxer(CreateFFmpegDemuxer()); #else return DEMUXER_ERROR_COULD_NOT_OPEN; #endif } else { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(!HasDataSource()); SetDemuxer(CreateChunkDemuxer()); is_static = false; @@ -502,7 +506,9 @@ const DataSource* DemuxerManager::GetDataSourceForTesting() const { } void DemuxerManager::SetDataSource(std::unique_ptr data_source) { + LOG(INFO) << "[NEU][CDM]" << __func__; data_source_ = std::move(data_source); + LOG(INFO) << "[NEU][CDM]" << __func__; } void DemuxerManager::OnBufferingHaveEnough(bool enough) { @@ -601,7 +607,7 @@ std::unique_ptr DemuxerManager::CreateChunkDemuxer() { FROM_HERE, base::BindRepeating(&DemuxerManager::OnMemoryPressure, base::Unretained(this))); } - + LOG(INFO) << "[NEU][CDM]" << __func__; return std::make_unique( base::BindPostTaskToCurrentDefault(base::BindOnce( &DemuxerManager::OnChunkDemuxerOpened, weak_factory_.GetWeakPtr())), @@ -615,6 +621,7 @@ std::unique_ptr DemuxerManager::CreateChunkDemuxer() { #if BUILDFLAG(ENABLE_FFMPEG) std::unique_ptr DemuxerManager::CreateFFmpegDemuxer() { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(data_source_); return std::make_unique( media_task_runner_, data_source_.get(), @@ -649,18 +656,21 @@ std::unique_ptr DemuxerManager::CreateMediaUrlDemuxer( void DemuxerManager::SetDemuxer(std::unique_ptr demuxer) { DCHECK(!demuxer_); CHECK(demuxer); - + LOG(INFO) << "[NEU][CDM]" << __func__; demuxer_ = std::move(demuxer); if (client_) { client_->MakeDemuxerThreadDumper(demuxer_.get()); } + LOG(INFO) << "[NEU][CDM]" << __func__; } void DemuxerManager::OnEncryptedMediaInitData( EmeInitDataType init_data_type, const std::vector& init_data) { + LOG(INFO) << "[NEU][CDM]" << __func__; if (client_) { client_->OnEncryptedMediaInitData(init_data_type, init_data); + LOG(INFO) << "[NEU][CDM]" << __func__; } } diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index ae9746e5f237d7a6e3a8352108278f3fbc83c205..625a9b439d5979233932c6dc07176a762acf866d 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc @@ -271,7 +271,7 @@ FFmpegDemuxerStream::FFmpegDemuxerStream( last_packet_pos_(AV_NOPTS_VALUE), last_packet_dts_(AV_NOPTS_VALUE) { DCHECK(demuxer_); - + LOG(INFO) << "[NEU][CDM]" << __func__; bool is_encrypted = false; // Determine our media format. @@ -315,6 +315,7 @@ FFmpegDemuxerStream::FFmpegDemuxerStream( encryption_key_id_.assign(enc_key_id); demuxer_->OnEncryptedMediaInitData(EmeInitDataType::WEBM, enc_key_id); } + LOG(INFO) << "[NEU][CDM]" << __func__; } FFmpegDemuxerStream::~FFmpegDemuxerStream() { @@ -1184,9 +1185,11 @@ FFmpegDemuxer::GetContainerForMetrics() const { void FFmpegDemuxer::OnEncryptedMediaInitData( EmeInitDataType init_data_type, const std::string& encryption_key_id) { + LOG(INFO) << "[NEU][CDM]" << __func__; std::vector key_id_local(encryption_key_id.begin(), encryption_key_id.end()); encrypted_media_init_data_cb_.Run(init_data_type, key_id_local); + LOG(INFO) << "[NEU][CDM]" << __func__; } void FFmpegDemuxer::NotifyCapacityAvailable() { diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc index 6b5e48095e4bc09371bb07d8de0e024776661899..aa99162d7c7d43a10d328c0f333f8228bbac1d2c 100644 --- a/media/filters/ffmpeg_video_decoder.cc +++ b/media/filters/ffmpeg_video_decoder.cc @@ -229,6 +229,7 @@ void FFmpegVideoDecoder::Initialize(const VideoDecoderConfig& config, InitCB init_cb, const OutputCB& output_cb, const WaitingCB& /* waiting_cb */) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__ << ": " << config.AsHumanReadableString(); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(config.IsValidConfig()); @@ -259,10 +260,12 @@ void FFmpegVideoDecoder::Initialize(const VideoDecoderConfig& config, output_cb_ = output_cb; state_ = DecoderState::kNormal; std::move(bound_init_cb).Run(DecoderStatus::Codes::kOk); + LOG(INFO) << "[NEU][CDM]" << __func__; } void FFmpegVideoDecoder::Decode(scoped_refptr buffer, DecodeCB decode_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(3) << __func__; DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(buffer.get()); @@ -314,6 +317,7 @@ void FFmpegVideoDecoder::Decode(scoped_refptr buffer, // VideoDecoderShim expects that |decode_cb| is called only after // |output_cb_|. std::move(decode_cb_bound).Run(DecoderStatus::Codes::kOk); + LOG(INFO) << "[NEU][CDM]" << __func__; } void FFmpegVideoDecoder::Reset(base::OnceClosure closure) { @@ -384,6 +388,7 @@ bool FFmpegVideoDecoder::FFmpegDecode(const DecoderBuffer& buffer) { } bool FFmpegVideoDecoder::OnNewFrame(AVFrame* frame) { + LOG(INFO) << "[NEU][CDM]" << __func__; // TODO(fbarchard): Work around for FFmpeg http://crbug.com/27675 // The decoder is in a bad state and not decoding correctly. // Checking for NULL avoids a crash in CopyPlane(). @@ -469,6 +474,7 @@ bool FFmpegVideoDecoder::OnNewFrame(AVFrame* frame) { video_frame->AddDestructionObserver( frame_pool_->CreateFrameCallback(opaque->fb_priv)); output_cb_.Run(video_frame); + LOG(INFO) << "[NEU][CDM]" << __func__; return true; } @@ -479,6 +485,7 @@ void FFmpegVideoDecoder::ReleaseFFmpegResources() { bool FFmpegVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config, bool low_delay) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(config.IsValidConfig()); DCHECK(!config.is_encrypted()); @@ -505,6 +512,7 @@ bool FFmpegVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config, } decoding_loop_ = std::make_unique(codec_context_.get()); + LOG(INFO) << "[NEU][CDM]" << __func__; return true; } diff --git a/media/filters/pipeline_controller.cc b/media/filters/pipeline_controller.cc index bb464421d27f4ed1a325c175290170e140b9fd25..53facfcd9570d1f7666db82b210f081b22b1b4b6 100644 --- a/media/filters/pipeline_controller.cc +++ b/media/filters/pipeline_controller.cc @@ -6,6 +6,7 @@ #include "base/functional/bind.h" #include "media/base/demuxer.h" +#include "base/logging.h" namespace media { @@ -38,6 +39,7 @@ void PipelineController::Start(Pipeline::StartType start_type, Pipeline::Client* client, bool is_streaming, bool is_static) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_EQ(state_, State::STOPPED); DCHECK(demuxer); @@ -57,6 +59,7 @@ void PipelineController::Start(Pipeline::StartType start_type, start_type == Pipeline::StartType::kNormal ? State::PLAYING : State::PLAYING_OR_SUSPENDED)); + LOG(INFO) << "[NEU][CDM]" << __func__; } void PipelineController::Seek(base::TimeDelta time, bool time_updated) { diff --git a/media/filters/source_buffer_state.cc b/media/filters/source_buffer_state.cc index ca3c451bdd511f13b2787be0375acaf9e2f3ea1c..a3765fbf83860d1b3899f7ca11693e0d83653bb5 100644 --- a/media/filters/source_buffer_state.cc +++ b/media/filters/source_buffer_state.cc @@ -628,7 +628,7 @@ void SourceBufferState::InitializeParser(const std::string& expected_codecs) { } MEDIA_LOG(INFO, media_log_) << "Unrecognized media codec: " << codec_id; } - + LOG(INFO) << "[NEU][CDM]" << __func__; stream_parser_->Init( base::BindOnce(&SourceBufferState::OnSourceInitDone, base::Unretained(this)), @@ -1050,6 +1050,7 @@ bool SourceBufferState::OnNewBuffers( void SourceBufferState::OnEncryptedMediaInitData( EmeInitDataType type, const std::vector& init_data) { + LOG(INFO) << "[NEU][CDM]" << __func__; encrypted_media_init_data_reported_ = true; encrypted_media_init_data_cb_.Run(type, init_data); } diff --git a/media/gpu/h264_decoder.cc b/media/gpu/h264_decoder.cc index e533d9f81e4f47efa01093def1fd6343bd05dad8..03f49e6f711995b2a7177a475f86da19c9ef3a22 100644 --- a/media/gpu/h264_decoder.cc +++ b/media/gpu/h264_decoder.cc @@ -1456,6 +1456,7 @@ void H264Decoder::SetStream(int32_t id, const DecoderBuffer& decoder_buffer) { } H264Decoder::DecodeResult H264Decoder::Decode() { + LOG(INFO) << "[NEU][CDM]" << __func__; if (state_ == State::kError) { DVLOG(1) << "Decoder in error state"; return kDecodeError; diff --git a/media/gpu/h265_decoder.cc b/media/gpu/h265_decoder.cc index 3c5b89e5d6b735ab01115a19fe2ae9804f32e664..4412911e45453d7c92d8967f9e5e15f17bf9c569 100644 --- a/media/gpu/h265_decoder.cc +++ b/media/gpu/h265_decoder.cc @@ -166,6 +166,7 @@ void H265Decoder::Reset() { } H265Decoder::DecodeResult H265Decoder::Decode() { + LOG(INFO) << "[NEU][CDM]" << __func__; if (state_ == kError) { DVLOG(1) << "Decoder in error state"; return kDecodeError; diff --git a/media/mojo/clients/mojo_cdm.cc b/media/mojo/clients/mojo_cdm.cc index d5b0d873524d6825726e14eab37a34b82585c742..34047c0bbdb62c34101c3bee9b2ef970af71cc3f 100644 --- a/media/mojo/clients/mojo_cdm.cc +++ b/media/mojo/clients/mojo_cdm.cc @@ -179,6 +179,7 @@ void MojoCdm::CreateSessionAndGenerateRequest( EmeInitDataType init_data_type, const std::vector& init_data, std::unique_ptr promise) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -204,6 +205,7 @@ void MojoCdm::CreateSessionAndGenerateRequest( base::BindOnce(&MojoCdm::OnNewSessionCdmPromiseResult, base::Unretained(this), promise_id), kMojoCdmTimeout, base::BindOnce(&OnCallbackTimeout, uma_name))); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MojoCdm::LoadSession(CdmSessionType session_type, @@ -229,6 +231,7 @@ void MojoCdm::LoadSession(CdmSessionType session_type, void MojoCdm::UpdateSession(const std::string& session_id, const std::vector& response, std::unique_ptr promise) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -244,6 +247,7 @@ void MojoCdm::UpdateSession(const std::string& session_id, session_id, response, base::BindOnce(&MojoCdm::OnSimpleCdmPromiseResult, base::Unretained(this), promise_id)); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MojoCdm::CloseSession(const std::string& session_id, diff --git a/media/mojo/clients/mojo_cdm_factory.cc b/media/mojo/clients/mojo_cdm_factory.cc index 60ee6ff5ab416a7509ce9d324b89d755aaf2e8f6..1bb61fcccfb294b817585be826368d37e600abeb 100644 --- a/media/mojo/clients/mojo_cdm_factory.cc +++ b/media/mojo/clients/mojo_cdm_factory.cc @@ -34,6 +34,7 @@ void OnCdmCreated( mojo::PendingRemote cdm_remote, media::mojom::CdmContextPtr cdm_context, const std::string& error_message) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", error_message: " << error_message; // Convert from a PendingRemote to Remote so we can verify that it is // connected, this will also check if |cdm_remote| is null. mojo::Remote remote(std::move(cdm_remote)); @@ -48,6 +49,7 @@ void OnCdmCreated( session_message_cb, session_closed_cb, session_keys_change_cb, session_expiration_update_cb), ""); + LOG(INFO) << "[NEU][CDM]" << __func__; } } // namespace @@ -68,7 +70,7 @@ void MojoCdmFactory::Create( const SessionExpirationUpdateCB& session_expiration_update_cb, CdmCreatedCB cdm_created_cb) { DVLOG(2) << __func__ << ": cdm_config=" << cdm_config; - + LOG(INFO) << "[NEU][CDM]" << __func__; // If AesDecryptor can be used, always use it here in the local process. // Note: We should not run AesDecryptor in the browser process except for // testing. See http://crbug.com/441957. @@ -80,6 +82,7 @@ void MojoCdmFactory::Create( session_keys_change_cb, session_expiration_update_cb)); base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(std::move(cdm_created_cb), cdm, "")); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } @@ -93,6 +96,7 @@ void MojoCdmFactory::Create( session_expiration_update_cb, std::move(cdm_created_cb)), mojo::NullRemote(), nullptr, "disconnection error")); + LOG(INFO) << "[NEU][CDM]" << __func__; } } // namespace media diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn index 1c022dff17ca90bcfdf0dfac683140a1a42ac37a..6174f2adb85aff60f1893f4032560fd58a38181f 100644 --- a/media/mojo/services/BUILD.gn +++ b/media/mojo/services/BUILD.gn @@ -117,7 +117,7 @@ component("services") { sources += [ "gpu_mojo_media_client_mac.cc" ] } else if (is_win) { sources += [ "gpu_mojo_media_client_win.cc" ] - } else if (enable_heif_decoder) { + } else if ((enable_heif_decoder) || ((defined(ohos_enable_cdm) && ohos_enable_cdm))) { sources += [ "gpu_mojo_media_client_ohos.cc" ] } else if (use_vaapi || use_v4l2_codec) { if (is_linux) { @@ -150,6 +150,15 @@ component("services") { ] } + if ((is_ohos) && (defined(ohos_enable_cdm) && ohos_enable_cdm)) { + sources += [ + "ohos_mojo_media_client.cc", + "ohos_mojo_media_client.h", + "ohos_mojo_util.cc", + "ohos_mojo_util.h", + ] + } + if (enable_media_drm_storage) { sources += [ "mojo_media_drm_storage.cc", diff --git a/media/mojo/services/cdm_service.cc b/media/mojo/services/cdm_service.cc index e584cbadeb6ffe79038aef2245483ca29e906382..4837632f2a01454b2f22ce2dc393f40f37b25a56 100644 --- a/media/mojo/services/cdm_service.cc +++ b/media/mojo/services/cdm_service.cc @@ -58,7 +58,7 @@ class CdmFactoryImpl final : public DeferredDestroy { void CreateCdm(const CdmConfig& cdm_config, CreateCdmCallback callback) final { DVLOG(2) << __func__; - + LOG(INFO) << "[NEU][CDM]" << __func__; auto* cdm_factory = GetCdmFactory(); if (!cdm_factory) { std::move(callback).Run(mojo::NullRemote(), nullptr, @@ -77,6 +77,7 @@ class CdmFactoryImpl final : public DeferredDestroy { base::BindOnce(&CdmFactoryImpl::OnCdmServiceInitialized, weak_ptr_factory_.GetWeakPtr(), raw_mojo_cdm_service, std::move(callback))); + LOG(INFO) << "[NEU][CDM]" << __func__; } // DeferredDestroy implemenation. diff --git a/media/mojo/services/gpu_mojo_media_client.cc b/media/mojo/services/gpu_mojo_media_client.cc index 35ed9c8db68250a256a55e2655c019e926ff31de..544301f817504b94eb44ee5e80c2b88ca94f6f10 100644 --- a/media/mojo/services/gpu_mojo_media_client.cc +++ b/media/mojo/services/gpu_mojo_media_client.cc @@ -254,6 +254,7 @@ std::unique_ptr GpuMojoMediaClient::CreateVideoDecoder( std::unique_ptr GpuMojoMediaClient::CreateCdmFactory( mojom::FrameInterfaceFactory* frame_interfaces) { + LOG(INFO) << "[NEU][CDM]" << __func__; return CreatePlatformCdmFactory(frame_interfaces); } diff --git a/media/mojo/services/gpu_mojo_media_client_ohos.cc b/media/mojo/services/gpu_mojo_media_client_ohos.cc index 1c9af5c0a9ce92fb20cf58a675358ece6af3fd04..5b3de3e56c620157a388efec1b723504ba348b35 100644 --- a/media/mojo/services/gpu_mojo_media_client_ohos.cc +++ b/media/mojo/services/gpu_mojo_media_client_ohos.cc @@ -22,12 +22,21 @@ #include "media/mojo/mojom/provision_fetcher.mojom.h" #include "media/mojo/services/mojo_media_drm_storage.h" #include "media/mojo/services/mojo_provision_fetcher.h" +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +#include "media/base/ohos/ohos_cdm_factory.h" +#include "media/mojo/services/ohos_mojo_util.h" +#endif +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +using media::ohos_mojo_util::CreateMediaDrmStorage; +using media::ohos_mojo_util::CreateProvisionFetcher; +#endif namespace media { std::unique_ptr CreatePlatformVideoDecoder( VideoDecoderTraits& traits) { LOG(INFO) << "CreatePlatformVideoDecoder"; +#if BUILDFLAG(ENABLE_HEIF_DECODER) scoped_refptr ref_counted_lock; ref_counted_lock = base::MakeRefCounted(); @@ -49,6 +58,9 @@ std::unique_ptr CreatePlatformVideoDecoder( std::move(image_provider), std::move(frame_info_helper), ref_counted_lock), ref_counted_lock); +#else + return nullptr; +#endif } absl::optional GetPlatformSupportedVideoDecoderConfigs( @@ -57,7 +69,11 @@ absl::optional GetPlatformSupportedVideoDecoderCon const gpu::GPUInfo& gpu_info, base::OnceCallback get_vda_configs) { LOG(INFO) << "GetPlatformSupportedVideoDecoderConfigs"; +#if BUILDFLAG(ENABLE_HEIF_DECODER) return OhosVideoDecoder::GetSupportedConfigs(); +#else + return std::vector(); +#endif } // Not support platform audio decoder in ohos now. @@ -79,11 +95,21 @@ VideoDecoderType GetPlatformDecoderImplementationType( return VideoDecoderType::kOHOS; } +#if BUILDFLAG(IS_OHOS) && defined(OHOS_ENABLE_CDM) +std::unique_ptr CreatePlatformCdmFactory( + mojom::FrameInterfaceFactory* frame_interfaces) { + LOG(INFO) << "[NEU][CDM]" << __func__; + return std::make_unique( + base::BindRepeating(&CreateProvisionFetcher, frame_interfaces), + base::BindRepeating(&CreateMediaDrmStorage, frame_interfaces)); +} +#else // There is no CdmFactory on ohos now. class CdmFactory {}; std::unique_ptr CreatePlatformCdmFactory( mojom::FrameInterfaceFactory* frame_interfaces) { return nullptr; } +#endif } // namespace media \ No newline at end of file diff --git a/media/mojo/services/interface_factory_impl.cc b/media/mojo/services/interface_factory_impl.cc index 1c4ecb915ca4035f2306718b5caeeb7fe07d03c1..99ffb9ffb4af8a1ced91384fb6c62a9fe17f9fcc 100644 --- a/media/mojo/services/interface_factory_impl.cc +++ b/media/mojo/services/interface_factory_impl.cc @@ -206,12 +206,15 @@ void InterfaceFactoryImpl::CreateMediaFoundationRenderer( void InterfaceFactoryImpl::CreateCdm(const CdmConfig& cdm_config, CreateCdmCallback callback) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; #if BUILDFLAG(ENABLE_MOJO_CDM) CdmFactory* cdm_factory = GetCdmFactory(); + LOG(INFO) << "[NEU][CDM]" << __func__; if (!cdm_factory) { std::move(callback).Run(mojo::NullRemote(), nullptr, "CDM Factory creation failed"); + LOG(INFO) << "[NEU][CDM]" << __func__; return; } @@ -226,9 +229,12 @@ void InterfaceFactoryImpl::CreateCdm(const CdmConfig& cdm_config, base::BindOnce(&InterfaceFactoryImpl::OnCdmServiceInitialized, weak_ptr_factory_.GetWeakPtr(), raw_mojo_cdm_service, std::move(callback))); + LOG(INFO) << "[NEU][CDM]" << __func__; #else // BUILDFLAG(ENABLE_MOJO_CDM) + LOG(INFO) << "[NEU][CDM]" << __func__; std::move(callback).Run(mojo::NullRemote(), nullptr, "Mojo CDM not supported"); + LOG(INFO) << "[NEU][CDM]" << __func__; #endif } @@ -324,10 +330,13 @@ void InterfaceFactoryImpl::AddRenderer( #if BUILDFLAG(ENABLE_MOJO_CDM) CdmFactory* InterfaceFactoryImpl::GetCdmFactory() { + LOG(INFO) << "[NEU][CDM]" << __func__; if (!cdm_factory_) { + LOG(INFO) << "[NEU][CDM]" << __func__; cdm_factory_ = mojo_media_client_->CreateCdmFactory(frame_interfaces_.get()); LOG_IF(ERROR, !cdm_factory_) << "CdmFactory not available."; + LOG(INFO) << "[NEU][CDM]" << __func__; } return cdm_factory_.get(); } @@ -338,7 +347,7 @@ void InterfaceFactoryImpl::OnCdmServiceInitialized( mojom::CdmContextPtr cdm_context, const std::string& error_message) { DCHECK(raw_mojo_cdm_service); - + LOG(INFO) << "[NEU][CDM]" << __func__ << ", " << error_message; // Remove pending MojoCdmService from the mapping in all cases. DCHECK(pending_mojo_cdm_services_.count(raw_mojo_cdm_service)); auto mojo_cdm_service = @@ -346,6 +355,7 @@ void InterfaceFactoryImpl::OnCdmServiceInitialized( pending_mojo_cdm_services_.erase(raw_mojo_cdm_service); if (!cdm_context) { + LOG(INFO) << "[NEU][CDM]" << __func__ << ", " << error_message; std::move(callback).Run(mojo::NullRemote(), nullptr, error_message); return; } @@ -354,6 +364,7 @@ void InterfaceFactoryImpl::OnCdmServiceInitialized( cdm_receivers_.Add(std::move(mojo_cdm_service), remote.InitWithNewPipeAndPassReceiver()); std::move(callback).Run(std::move(remote), std::move(cdm_context), ""); + LOG(INFO) << "[NEU][CDM]" << __func__; } #endif // BUILDFLAG(ENABLE_MOJO_CDM) diff --git a/media/mojo/services/media_foundation_service.cc b/media/mojo/services/media_foundation_service.cc index 8f0caa6c26c0afe8777a24a86517b8c761644bbd..fd0efd8cf64cce30a5c43720269dadf4c20e1e82 100644 --- a/media/mojo/services/media_foundation_service.cc +++ b/media/mojo/services/media_foundation_service.cc @@ -471,11 +471,13 @@ void MediaFoundationService::IsKeySystemSupported( void MediaFoundationService::CreateInterfaceFactory( mojo::PendingReceiver receiver, mojo::PendingRemote frame_interfaces) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; interface_factory_receivers_.Add( std::make_unique(std::move(frame_interfaces), &mojo_media_client_), std::move(receiver)); + LOG(INFO) << "[NEU][CDM]" << __func__; } } // namespace media diff --git a/media/mojo/services/media_service.cc b/media/mojo/services/media_service.cc index f9806d87d92c2578ae74819e5ee0020ca0b24053..2199431da2b4d9875154392063bf75748ffd30bf 100644 --- a/media/mojo/services/media_service.cc +++ b/media/mojo/services/media_service.cc @@ -26,6 +26,7 @@ MediaService::~MediaService() = default; void MediaService::CreateInterfaceFactory( mojo::PendingReceiver receiver, mojo::PendingRemote frame_interfaces) { + LOG(INFO) << "[NEU][CDM]" << __func__; // Ignore request if service has already stopped. if (!mojo_media_client_) return; @@ -34,6 +35,7 @@ void MediaService::CreateInterfaceFactory( std::make_unique(std::move(frame_interfaces), mojo_media_client_.get()), std::move(receiver)); + LOG(INFO) << "[NEU][CDM]" << __func__; } } // namespace media diff --git a/media/mojo/services/media_service_factory.cc b/media/mojo/services/media_service_factory.cc index 72f264a615111342cb6c78cbcc85dd4897e35656..bb2f8e0263c17a1963eb8d4045edf110b19b9f4f 100644 --- a/media/mojo/services/media_service_factory.cc +++ b/media/mojo/services/media_service_factory.cc @@ -26,6 +26,7 @@ namespace media { std::unique_ptr CreateMediaService( mojo::PendingReceiver receiver) { + LOG(INFO) << "[NEU][CDM]-----" << __func__; #if BUILDFLAG(IS_ANDROID) return std::make_unique( std::make_unique(), std::move(receiver)); @@ -34,6 +35,7 @@ std::unique_ptr CreateMediaService( std::make_unique(), std::move(receiver)); #else NOTREACHED() << "No MediaService implementation available."; + LOG(INFO) << "[NEU][CDM]-----" << __func__; return nullptr; #endif } @@ -48,6 +50,7 @@ std::unique_ptr CreateGpuMediaService( base::WeakPtr media_gpu_channel_manager, gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory, AndroidOverlayMojoFactoryCB android_overlay_factory_cb) { + LOG(INFO) << "[NEU][CDM]-----" << __func__; return std::make_unique( std::make_unique( gpu_preferences, gpu_workarounds, gpu_feature_info, gpu_info, diff --git a/media/mojo/services/mojo_cdm_service.cc b/media/mojo/services/mojo_cdm_service.cc index 42df460c99b1f44d138f82d8fddc44d9ecebc685..a5e95679e9c0425265dacce4662ac5d5a90b133e 100644 --- a/media/mojo/services/mojo_cdm_service.cc +++ b/media/mojo/services/mojo_cdm_service.cc @@ -51,6 +51,7 @@ MojoCdmService::~MojoCdmService() { void MojoCdmService::Initialize(CdmFactory* cdm_factory, const CdmConfig& cdm_config, InitializeCB init_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; auto weak_this = weak_factory_.GetWeakPtr(); cdm_factory->Create( cdm_config, @@ -63,6 +64,7 @@ void MojoCdmService::Initialize(CdmFactory* cdm_factory, mojo::WrapCallbackWithDefaultInvokeIfNotRun( std::move(init_cb), nullptr, "Mojo CDM Service creation aborted"))); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MojoCdmService::SetClient( @@ -93,10 +95,12 @@ void MojoCdmService::CreateSessionAndGenerateRequest( EmeInitDataType init_data_type, const std::vector& init_data, CreateSessionAndGenerateRequestCallback callback) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; cdm_->CreateSessionAndGenerateRequest( session_type, init_data_type, init_data, std::make_unique(std::move(callback))); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MojoCdmService::LoadSession(CdmSessionType session_type, @@ -111,10 +115,12 @@ void MojoCdmService::LoadSession(CdmSessionType session_type, void MojoCdmService::UpdateSession(const std::string& session_id, const std::vector& response, UpdateSessionCallback callback) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(2) << __func__; cdm_->UpdateSession( session_id, response, std::make_unique(std::move(callback))); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MojoCdmService::CloseSession(const std::string& session_id, @@ -149,9 +155,10 @@ void MojoCdmService::OnCdmCreated( std::move(init_cb).Run(nullptr, non_empty_error_message); return; } - + LOG(INFO) << "[NEU][CDM]" << __func__; cdm_ = cdm; cdm_id_ = context_->RegisterCdm(this); + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__ << ": CDM successfully registered with ID " << CdmContext::CdmIdToString(base::OptionalToPtr(cdm_id_)); diff --git a/media/mojo/services/mojo_cdm_service_context.cc b/media/mojo/services/mojo_cdm_service_context.cc index fb0e4b2ab8c9bf99c4ff974587a66682da8487ae..22f06120066dbea77f93e36a5a0b6872cb60aef7 100644 --- a/media/mojo/services/mojo_cdm_service_context.cc +++ b/media/mojo/services/mojo_cdm_service_context.cc @@ -30,10 +30,12 @@ MojoCdmServiceContext::~MojoCdmServiceContext() = default; base::UnguessableToken MojoCdmServiceContext::RegisterCdm( MojoCdmService* cdm_service) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(cdm_service); base::UnguessableToken cdm_id = GetNextCdmId(); cdm_services_[cdm_id] = cdm_service; DVLOG(1) << __func__ << ": CdmService registered with CDM ID " << cdm_id; + LOG(INFO) << "[NEU][CDM]" << __func__; return cdm_id; } diff --git a/media/mojo/services/mojo_media_client.cc b/media/mojo/services/mojo_media_client.cc index 1f93e03e7b412266284e0c62c4d191c0027fb7ab..fc000c621856193ae65ca9168359434b4ba5c779 100644 --- a/media/mojo/services/mojo_media_client.cc +++ b/media/mojo/services/mojo_media_client.cc @@ -94,6 +94,7 @@ std::unique_ptr MojoMediaClient::CreateMediaFoundationRenderer( std::unique_ptr MojoMediaClient::CreateCdmFactory( mojom::FrameInterfaceFactory* frame_interfaces) { + LOG(INFO) << "[NEU][CDM]" << __func__; return nullptr; } diff --git a/media/mojo/services/mojo_media_drm_storage.cc b/media/mojo/services/mojo_media_drm_storage.cc index d9efabbea48bc19e31544422bf1a6f7c308b8a3e..8e18ce52d71fedf923d3ba7e597ae7baae30eba7 100644 --- a/media/mojo/services/mojo_media_drm_storage.cc +++ b/media/mojo/services/mojo_media_drm_storage.cc @@ -28,12 +28,15 @@ MojoMediaDrmStorage::MojoMediaDrmStorage( MojoMediaDrmStorage::~MojoMediaDrmStorage() {} void MojoMediaDrmStorage::Initialize(InitCB init_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; media_drm_storage_->Initialize(mojo::WrapCallbackWithDefaultInvokeIfNotRun( std::move(init_cb), false, absl::nullopt)); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MojoMediaDrmStorage::OnProvisioned(ResultCB result_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; media_drm_storage_->OnProvisioned( mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(result_cb), false)); @@ -42,17 +45,20 @@ void MojoMediaDrmStorage::OnProvisioned(ResultCB result_cb) { void MojoMediaDrmStorage::SavePersistentSession(const std::string& session_id, const SessionData& session_data, ResultCB result_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; media_drm_storage_->SavePersistentSession( session_id, mojom::SessionData::New(session_data.key_set_id, session_data.mime_type, session_data.key_type), mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(result_cb), false)); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MojoMediaDrmStorage::LoadPersistentSession( const std::string& session_id, LoadPersistentSessionCB load_persistent_session_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; media_drm_storage_->LoadPersistentSession( session_id, @@ -61,6 +67,7 @@ void MojoMediaDrmStorage::LoadPersistentSession( weak_factory_.GetWeakPtr(), std::move(load_persistent_session_cb)), nullptr)); + LOG(INFO) << "[NEU][CDM]" << __func__; } void MojoMediaDrmStorage::RemovePersistentSession(const std::string& session_id, @@ -75,7 +82,7 @@ void MojoMediaDrmStorage::OnPersistentSessionLoaded( LoadPersistentSessionCB load_persistent_session_cb, mojom::SessionDataPtr session_data) { DVLOG(1) << __func__ << ": success = " << !!session_data; - + LOG(INFO) << "[NEU][CDM]" << __func__ << ": success = " << !!session_data; std::move(load_persistent_session_cb) .Run(session_data ? std::make_unique( diff --git a/media/mojo/services/ohos_mojo_media_client.cc b/media/mojo/services/ohos_mojo_media_client.cc new file mode 100644 index 0000000000000000000000000000000000000000..6bc36273e1244dcc1cf0103268fcec4af6fac891 --- /dev/null +++ b/media/mojo/services/ohos_mojo_media_client.cc @@ -0,0 +1,49 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/mojo/services/ohos_mojo_media_client.h" + +#include + +#include + +#include "base/functional/bind.h" +#include "base/task/single_thread_task_runner.h" +#include "media/base/audio_decoder.h" +#include "media/base/cdm_factory.h" +#include "media/base/media_log.h" +#include "media/base/ohos/ohos_cdm_factory.h" +#include "media/mojo/mojom/media_drm_storage.mojom.h" +#include "media/mojo/mojom/provision_fetcher.mojom.h" +#include "media/mojo/services/ohos_mojo_util.h" + +using media::ohos_mojo_util::CreateMediaDrmStorage; +using media::ohos_mojo_util::CreateProvisionFetcher; + +namespace media { + +OHOSMojoMediaClient::OHOSMojoMediaClient() {} + +OHOSMojoMediaClient::~OHOSMojoMediaClient() {} + +std::unique_ptr OHOSMojoMediaClient::CreateAudioDecoder( + scoped_refptr task_runner, + std::unique_ptr media_log) { + return nullptr; +} + +std::unique_ptr OHOSMojoMediaClient::CreateCdmFactory( + mojom::FrameInterfaceFactory* frame_interfaces) { + if (!frame_interfaces) { + NOTREACHED() << "Host interfaces should be provided when using CDM with " + << "OHOSMojoMediaClient"; + return nullptr; + } + + return std::make_unique( + base::BindRepeating(&CreateProvisionFetcher, frame_interfaces), + base::BindRepeating(&CreateMediaDrmStorage, frame_interfaces)); +} + +} // namespace media diff --git a/media/mojo/services/ohos_mojo_media_client.h b/media/mojo/services/ohos_mojo_media_client.h new file mode 100644 index 0000000000000000000000000000000000000000..bd6ebd6f57835b20e3ed5be9f85b69d12d5e2152 --- /dev/null +++ b/media/mojo/services/ohos_mojo_media_client.h @@ -0,0 +1,34 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_MOJO_SERVICES_OHOS_MOJO_MEDIA_CLIENT_H_ +#define MEDIA_MOJO_SERVICES_OHOS_MOJO_MEDIA_CLIENT_H_ + +#include + +#include "base/task/sequenced_task_runner.h" +#include "media/mojo/services/mojo_media_client.h" + +namespace media { + +class OHOSMojoMediaClient final : public MojoMediaClient { + public: + OHOSMojoMediaClient(); + + OHOSMojoMediaClient(const OHOSMojoMediaClient&) = delete; + OHOSMojoMediaClient& operator=(const OHOSMojoMediaClient&) = delete; + + ~OHOSMojoMediaClient() override; + + std::unique_ptr CreateAudioDecoder( + scoped_refptr task_runner, + std::unique_ptr media_log) override; + + std::unique_ptr CreateCdmFactory( + mojom::FrameInterfaceFactory* frame_interfaces) override; +}; + +} // namespace media + +#endif // MEDIA_MOJO_SERVICES_OHOS_MOJO_MEDIA_CLIENT_H_ diff --git a/media/mojo/services/ohos_mojo_util.cc b/media/mojo/services/ohos_mojo_util.cc new file mode 100644 index 0000000000000000000000000000000000000000..911377c794177e7255d0c2b0818da4e379e22feb --- /dev/null +++ b/media/mojo/services/ohos_mojo_util.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/mojo/services/ohos_mojo_util.h" + +#include "media/mojo/services/mojo_media_drm_storage.h" +#include "mojo/public/cpp/bindings/pending_remote.h" + +namespace media { +namespace ohos_mojo_util { + +std::unique_ptr CreateProvisionFetcher( + media::mojom::FrameInterfaceFactory* frame_interfaces) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(frame_interfaces); + mojo::PendingRemote provision_fetcher; + frame_interfaces->CreateProvisionFetcher( + provision_fetcher.InitWithNewPipeAndPassReceiver()); + LOG(INFO) << "[NEU][CDM]" << __func__; + return std::make_unique(std::move(provision_fetcher)); +} + +std::unique_ptr CreateMediaDrmStorage( + media::mojom::FrameInterfaceFactory* frame_interfaces) { + LOG(INFO) << "[NEU][CDM]" << __func__; + DCHECK(frame_interfaces); + mojo::PendingRemote media_drm_storage; + frame_interfaces->BindEmbedderReceiver(mojo::GenericPendingReceiver( + media_drm_storage.InitWithNewPipeAndPassReceiver())); + LOG(INFO) << "[NEU][CDM]" << __func__; + return std::make_unique(std::move(media_drm_storage)); +} + +} // namespace ohos_mojo_util +} // namespace media diff --git a/media/mojo/services/ohos_mojo_util.h b/media/mojo/services/ohos_mojo_util.h new file mode 100644 index 0000000000000000000000000000000000000000..55ebb278d89476fa6c7466465e86170b161f9a60 --- /dev/null +++ b/media/mojo/services/ohos_mojo_util.h @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_MOJO_SERVICES_OHOS_MOJO_UTIL_H_ +#define MEDIA_MOJO_SERVICES_OHOS_MOJO_UTIL_H_ + +#include + +#include "media/mojo/mojom/frame_interface_factory.mojom.h" +#include "media/mojo/services/mojo_media_drm_storage.h" +#include "media/mojo/services/mojo_provision_fetcher.h" + +namespace media { +namespace ohos_mojo_util { + +std::unique_ptr CreateProvisionFetcher( + media::mojom::FrameInterfaceFactory* frame_interfaces); + +std::unique_ptr CreateMediaDrmStorage( + media::mojom::FrameInterfaceFactory* frame_interfaces); + +} // namespace ohos_mojo_util +} // namespace media + +#endif // MEDIA_MOJO_SERVICES_OHOS_MOJO_UTIL_H_ diff --git a/media/renderers/default_decoder_factory.cc b/media/renderers/default_decoder_factory.cc index 45a83042d207bc1bd30f734ebf98eccb942917ea..63875cd6e77d76bff3f033e94ac4c9eb66d8c983 100644 --- a/media/renderers/default_decoder_factory.cc +++ b/media/renderers/default_decoder_factory.cc @@ -93,6 +93,7 @@ void DefaultDecoderFactory::CreateVideoDecoders( base::AutoLock auto_lock(shutdown_lock_); if (is_shutdown_) return; + LOG(INFO) << "[NEU][CDM]" << __func__; #if !BUILDFLAG(IS_ANDROID) video_decoders->push_back( @@ -121,10 +122,11 @@ void DefaultDecoderFactory::CreateVideoDecoders( video_decoders->push_back( std::make_unique(media_log)); #endif - + LOG(INFO) << "[NEU][CDM]" << __func__; #if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) video_decoders->push_back(std::make_unique(media_log)); #endif + LOG(INFO) << "[NEU][CDM]" << __func__; } base::WeakPtr DefaultDecoderFactory::GetWeakPtr() { diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc index 873dc8cb3f1bdcf59b220b748bf61e016c73c08b..b0d21a02ede8529fc4b3c10e20616363adac1136 100644 --- a/media/renderers/renderer_impl.cc +++ b/media/renderers/renderer_impl.cc @@ -143,7 +143,7 @@ void RendererImpl::Initialize(MediaResource* media_resource, DCHECK(client); TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "RendererImpl::Initialize", TRACE_ID_LOCAL(this)); - + LOG(INFO) << "[NEU][CDM]" << __func__; client_ = client; media_resource_ = media_resource; init_cb_ = std::move(init_cb); @@ -161,6 +161,7 @@ void RendererImpl::Initialize(MediaResource* media_resource, void RendererImpl::SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DVLOG(1) << __func__; DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(cdm_context); diff --git a/media/renderers/renderer_impl_factory.cc b/media/renderers/renderer_impl_factory.cc index e7dd8daf9fcada7059b213fcb6fba3563d8f3bd2..2ea3c61319469a5771004abe125b18e54967749c 100644 --- a/media/renderers/renderer_impl_factory.cc +++ b/media/renderers/renderer_impl_factory.cc @@ -85,7 +85,7 @@ std::unique_ptr RendererImplFactory::CreateRenderer( RequestOverlayInfoCB request_overlay_info_cb, const gfx::ColorSpace& target_color_space) { DCHECK(audio_renderer_sink); - + LOG(INFO) << "[NEU][CDM]" << __func__; std::unique_ptr audio_renderer(new AudioRendererImpl( media_task_runner, audio_renderer_sink, // Unretained is safe here, because the RendererFactory is guaranteed to @@ -114,7 +114,7 @@ std::unique_ptr RendererImplFactory::CreateRenderer( gmb_pool = std::make_unique( media_task_runner, std::move(worker_task_runner), gpu_factories); } - + LOG(INFO) << "[NEU][CDM]" << __func__; std::unique_ptr video_renderer(new VideoRendererImpl( media_task_runner, video_renderer_sink, // Unretained is safe here, because the RendererFactory is guaranteed to diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc index fd264fe2caf7f6209369cf4d87f849ac992b9bb9..d0db1f2b3219397df4d0c53f546c0075c403b8d7 100644 --- a/media/renderers/video_renderer_impl.cc +++ b/media/renderers/video_renderer_impl.cc @@ -164,6 +164,7 @@ void VideoRendererImpl::Initialize( RendererClient* client, const TimeSource::WallClockTimeCB& wall_clock_time_cb, PipelineStatusCallback init_cb) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "VideoRendererImpl::Initialize", TRACE_ID_LOCAL(this)); @@ -222,6 +223,7 @@ void VideoRendererImpl::Initialize( weak_factory_.GetWeakPtr()), base::BindRepeating(&VideoRendererImpl::OnWaiting, weak_factory_.GetWeakPtr())); + LOG(INFO) << "[NEU][CDM]" << __func__; } scoped_refptr VideoRendererImpl::Render( @@ -565,6 +567,7 @@ void VideoRendererImpl::UpdateLatencyHintBufferingCaps_Locked( } void VideoRendererImpl::FrameReady(VideoDecoderStream::ReadResult result) { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(task_runner_->RunsTasksInCurrentSequence()); base::AutoLock auto_lock(lock_); DCHECK_EQ(state_, kPlaying); @@ -700,6 +703,7 @@ void VideoRendererImpl::FrameReady(VideoDecoderStream::ReadResult result) { // Always request more decoded video if we have capacity. AttemptRead_Locked(); + LOG(INFO) << "[NEU][CDM]" << __func__; } bool VideoRendererImpl::HaveEnoughData_Locked() const { @@ -776,6 +780,7 @@ void VideoRendererImpl::AddReadyFrame_Locked(scoped_refptr frame) { } void VideoRendererImpl::AttemptRead_Locked() { + LOG(INFO) << "[NEU][CDM]" << __func__; DCHECK(task_runner_->RunsTasksInCurrentSequence()); lock_.AssertAcquired(); @@ -791,6 +796,7 @@ void VideoRendererImpl::AttemptRead_Locked() { video_decoder_stream_->Read( base::BindOnce(&VideoRendererImpl::FrameReady, cancel_on_flush_weak_factory_.GetWeakPtr())); + LOG(INFO) << "[NEU][CDM]" << __func__; return; case kUninitialized: case kInitializing: diff --git a/ohos_build/build/config/ohos.json b/ohos_build/build/config/ohos.json index 7ec779d0adfebb63b6f967a79ec9165c504851eb..586932fc6ebee9e2ae1c914ac9e60c57040c69f2 100644 --- a/ohos_build/build/config/ohos.json +++ b/ohos_build/build/config/ohos.json @@ -295,6 +295,15 @@ "dependence": "", "default": "true" }, +{ + "name": "OHOS_ENABLE_CDM", + "owner": "", + "desc": "", + "effect":"main gn blink_core other", + "genCommandline": "default", + "dependence": "", + "default": "true" +}, { "name": "OHOS_ENABLE_POINTER_HARDENED", "owner": "",