Skip to content

Commit

Permalink
[Cast] Avoid old Android IPC used to check for key system support
Browse files Browse the repository at this point in the history
Previously each renderer on Android would check for key system support
by using cdm::QueryKeySystemSupport(), which uses the old IPC protocol.
New way is to use the KeySystemSupport mojo interface where key
systems are registered in the browser, and renderers subscribe to
notifications. This matches what is being done for desktop browsers
(and Chrome on Android).

KeySystemSupport allows for delayed determination of what features are
supported until the first time it is queried. So registration in the
browser is done without specifying any capabilities, and they will be
computed the first time they are needed.

Bug: 853336
Change-Id: Icd4b10f3c45e9c9cf48de19b09bb15ac1ff861bc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4313470
Reviewed-by: Xiaohan Wang <xhwang@chromium.org>
Reviewed-by: Yuchen Liu <yucliu@chromium.org>
Commit-Queue: John Rummell <jrummell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1202929}
  • Loading branch information
jrummell-chromium authored and Chromium LUCI CQ committed Sep 28, 2023
1 parent 0024fe7 commit 7494194
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 63 deletions.
16 changes: 0 additions & 16 deletions chromecast/browser/cast_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@
#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#include "chromecast/media/audio/cast_audio_manager_android.h" // nogncheck
#include "components/cdm/browser/cdm_message_filter_android.h"
#include "components/crash/core/app/crashpad.h"
#include "media/audio/android/audio_manager_android.h"
#include "media/audio/audio_features.h"
Expand Down Expand Up @@ -366,21 +365,6 @@ CastContentBrowserClient::CreateBrowserMainParts(
return main_parts;
}

void CastContentBrowserClient::RenderProcessWillLaunch(
content::RenderProcessHost* host) {
#if BUILDFLAG(IS_ANDROID)
// Cast on Android always allows persisting data.
//
// Cast on Android build always uses kForceVideoOverlays command line switch
// such that secure codecs can always be rendered.
//
// TODO(yucliu): On Clank, secure codecs support is tied to AndroidOverlay.
// Remove kForceVideoOverlays and switch to the Clank model for secure codecs
// support.
host->AddFilter(new cdm::CdmMessageFilterAndroid(true, true));
#endif // BUILDFLAG(IS_ANDROID)
}

bool CastContentBrowserClient::IsHandledURL(const GURL& url) {
if (!url.is_valid()) {
return false;
Expand Down
1 change: 0 additions & 1 deletion chromecast/browser/cast_content_browser_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ class CastContentBrowserClient
// content::ContentBrowserClient implementation:
std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(
bool is_integration_test) override;
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
bool IsHandledURL(const GURL& url) override;
void SiteInstanceGotProcess(content::SiteInstance* site_instance) override;
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
Expand Down
31 changes: 30 additions & 1 deletion chromecast/common/cast_content_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "components/cast/common/constants.h"
#include "content/public/common/cdm_info.h"
#include "media/base/media_switches.h"
#include "media/cdm/cdm_type.h"
#include "media/media_buildflags.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "third_party/widevine/cdm/buildflags.h"
Expand All @@ -31,6 +32,8 @@

#if BUILDFLAG(IS_ANDROID)
#include "chromecast/common/media/cast_media_drm_bridge_client.h"
#include "components/cdm/common/android_cdm_registration.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#endif

#if !BUILDFLAG(IS_FUCHSIA)
Expand Down Expand Up @@ -202,7 +205,33 @@ void CastContentClient::AddContentDecryptionModules(
} else {
DVLOG(1) << "Widevine enabled but no library found";
}

#elif BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(ENABLE_WIDEVINE)
cdm::AddAndroidWidevineCdm(cdms);
#endif // BUILDFLAG(ENABLE_WIDEVINE)

#if BUILDFLAG(ENABLE_PLAYREADY)
// PlayReady may be supported on the devices. Register it anyway without
// any capabilities so that it will be checked the first time it is used.
// CdmInfo needs a CdmType, but on Android it is not used as the key system
// is supported by MediaDrm. Using a random value as something needs to be
// specified, and it must be different than other CdmTypes specified.
// (On Android the key system is identified by UUID, and that mapping is
// maintained by MediaDrmBridge.)
const ::media::CdmType kPlayReadyCdmType{0x86eb6b54497627b0ull,
0xdd48f67486daf152ull};
// TODO(jrummell): Move kChromecastPlayreadyKeySystem from
// chromecast/media/base/key_systems_common.h to someplace more accessible.
const char kChromecastPlayreadyKeySystem[] = "com.chromecast.playready";
cdms->push_back(
content::CdmInfo(kChromecastPlayreadyKeySystem,
content::CdmInfo::Robustness::kSoftwareSecure,
absl::nullopt, kPlayReadyCdmType));
cdms->push_back(
content::CdmInfo(kChromecastPlayreadyKeySystem,
content::CdmInfo::Robustness::kHardwareSecure,
absl::nullopt, kPlayReadyCdmType));
#endif // BUILDFLAG(ENABLE_PLAYREADY)
#endif // BUILDFLAG(BUNDLE_WIDEVINE_CDM) && BUILDFLAG(IS_LINUX)
}
}
Expand Down
1 change: 1 addition & 0 deletions chromecast/renderer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ cast_source_set("renderer") {
"//chromecast/media",
"//chromecast/media/base:media_codec_support",
"//chromecast/renderer/media",
"//components/cdm/renderer",
"//components/media_control/renderer",
"//components/network_hints/renderer",
"//components/on_load_script_injector/renderer",
Expand Down
7 changes: 7 additions & 0 deletions chromecast/renderer/cast_content_renderer_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "media/base/audio_parameters.h"
#include "media/base/key_system_info.h"
#include "media/base/media.h"
#include "media/remoting/receiver_controller.h"
#include "media/remoting/remoting_constants.h"
Expand All @@ -50,6 +51,7 @@
#if BUILDFLAG(IS_ANDROID)
#include "base/android/bundle_utils.h"
#include "chromecast/media/audio/cast_audio_device_factory.h"
#include "components/cdm/renderer/key_system_support_update.h"
#include "media/base/android/media_codec_util.h"
#else
#include "chromecast/renderer/memory_pressure_observer_impl.h"
Expand Down Expand Up @@ -170,11 +172,16 @@ void CastContentRendererClient::RunScriptsAtDocumentEnd(

void CastContentRendererClient::GetSupportedKeySystems(
::media::GetSupportedKeySystemsCB cb) {
#if BUILDFLAG(IS_ANDROID)
cdm::GetSupportedKeySystemsUpdates(
/*can_persist_data=*/true, std::move(cb));
#else
::media::KeySystemInfos key_systems;
media::AddChromecastKeySystems(&key_systems,
false /* enable_persistent_license_support */,
false /* enable_playready */);
std::move(cb).Run(std::move(key_systems));
#endif // BUILDFLAG(IS_ANDROID)
}

bool CastContentRendererClient::IsSupportedAudioType(
Expand Down
51 changes: 9 additions & 42 deletions chromecast/renderer/media/key_systems_cast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class PlayReadyKeySystemInfo : public ::media::KeySystemInfo {
persistent_license_support_(persistent_license_support) {
}

std::string GetKeySystemName() const override {
std::string GetBaseKeySystemName() const override {
return media::kChromecastPlayreadyKeySystem;
}

Expand Down Expand Up @@ -81,20 +81,20 @@ class PlayReadyKeySystemInfo : public ::media::KeySystemInfo {
#if BUILDFLAG(IS_ANDROID)
return EmeConfig{.hw_secure_codecs = EmeConfigRuleState::kRequired};
#else
return media::EmeConfig::SupportedRule();
return EmeConfig::SupportedRule();
#endif // BUILDFLAG(IS_ANDROID)
}

// Cast-specific PlayReady implementation does not currently recognize or
// support non-empty robustness strings.
return media::EmeConfig::UnsupportedRule();
return EmeConfig::UnsupportedRule();
}

EmeConfig::Rule GetPersistentLicenseSessionSupport() const override {
if (persistent_license_support_) {
return media::EmeConfig::SupportedRule();
return EmeConfig::SupportedRule();
} else {
return media::EmeConfig::UnsupportedRule();
return EmeConfig::UnsupportedRule();
}
}

Expand All @@ -108,9 +108,9 @@ class PlayReadyKeySystemInfo : public ::media::KeySystemInfo {
EmeConfig::Rule GetEncryptionSchemeConfigRule(
EncryptionScheme encryption_scheme) const override {
if (encryption_scheme == EncryptionScheme::kCenc) {
return media::EmeConfig::SupportedRule();
return EmeConfig::SupportedRule();
} else {
return media::EmeConfig::UnsupportedRule();
return EmeConfig::UnsupportedRule();
}
}

Expand Down Expand Up @@ -198,51 +198,18 @@ void AddCmaKeySystems(::media::KeySystemInfos* key_system_infos,
EmeFeatureSupport::ALWAYS_ENABLED)); // Distinctive identifier.
#endif // BUILDFLAG(ENABLE_WIDEVINE)
}
#elif BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(ENABLE_PLAYREADY)
void AddCastPlayreadyKeySystemAndroid(
::media::KeySystemInfos* key_system_infos) {
DCHECK(key_system_infos);
SupportedKeySystemResponse response =
cdm::QueryKeySystemSupport(kChromecastPlayreadyKeySystem);

if (response.non_secure_codecs == ::media::EME_CODEC_NONE)
return;

key_system_infos->emplace_back(new PlayReadyKeySystemInfo(
response.non_secure_codecs, response.secure_codecs,
false /* persistent_license_support */));
}
#endif // BUILDFLAG(ENABLE_PLAYREADY)

void AddCastAndroidKeySystems(
::media::KeySystemInfos* key_system_infos,
bool enable_playready) {
#if BUILDFLAG(ENABLE_PLAYREADY)
if (enable_playready) {
AddCastPlayreadyKeySystemAndroid(key_system_infos);
}
#endif // BUILDFLAG(ENABLE_PLAYREADY)

#if BUILDFLAG(ENABLE_WIDEVINE)
cdm::AddAndroidWidevine(key_system_infos);
#endif // BUILDFLAG(ENABLE_WIDEVINE)
}
#endif // BUILDFLAG(IS_ANDROID)
#endif // BUILDFLAG(USE_CHROMECAST_CDMS) || BUILDFLAG(ENABLE_LIBRARY_CDMS)

} // namespace

// TODO(yucliu): Split CMA/Android logics into their own files.
void AddChromecastKeySystems(
::media::KeySystemInfos* key_system_infos,
bool enable_persistent_license_support,
bool enable_playready) {
#if BUILDFLAG(USE_CHROMECAST_CDMS) || BUILDFLAG(ENABLE_LIBRARY_CDMS)
AddCmaKeySystems(key_system_infos, enable_persistent_license_support,
enable_playready);
#elif BUILDFLAG(IS_ANDROID)
AddCastAndroidKeySystems(key_system_infos, enable_playready);
#endif // BUILDFLAG(IS_ANDROID)
#endif // BUILDFLAG(USE_CHROMECAST_CDMS) || BUILDFLAG(ENABLE_LIBRARY_CDMS)
}

} // namespace media
Expand Down
6 changes: 3 additions & 3 deletions content/browser/media/key_system_support_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "media/base/media_switches.h"
#include "media/base/media_util.h"
#include "media/base/video_codecs.h"
#include "media/media_buildflags.h"

using media::MediaCodecUtil;
using media::MediaDrmBridge;
Expand Down Expand Up @@ -83,10 +84,9 @@ void GetAndroidCdmCapability(const std::string& key_system,
return;
}

// Rendering of hardware secure codecs is only supported when AndroidOverlay
// is enabled.
if (is_secure) {
// Rendering of hardware secure codecs is only supported when
// AndroidOverlay is enabled.
// TODO(crbug.com/853336): Allow Cast override.
bool are_overlay_supported =
content::AndroidOverlayProvider::GetInstance()->AreOverlaysSupported();
bool overlay_fullscreen_video =
Expand Down

0 comments on commit 7494194

Please sign in to comment.