Commit bcd68581 authored by xhwang's avatar xhwang Committed by Commit bot

media: Add External Clear Key content browser test on Android

This CL adds External Clear Key support on Android for testing.
This is implemented by running AesDecryptor in the MojoCdmService,
which runs in the MojoMediaApplication in the GPU process. This is
only enabled when kExternalClearKeyForTesting feature is enabled.

A new content browser test is added to use External Clear Key on
Android. Since AesDecryptor doesn't support decoding, the media
pipeline is configured to do decrypt-only using the mojo CDM
(MojoDecryptor on MojoCdm), and then use the normal Android
pipeline (AVDA/MojoAudioDecoder) to decode encrypted audio/video.

Note that this is different from the default mode how Android
media pipeline works for encrypted content (decryption/decoding
both happens in the GPU process). When browser_tests are enabled
on Android, we should be able to have test coverage on that.

Here's what the new test covers:
- MojoCdm / MojoCdmService
- MojoDecryptor / MojoDecryptorService
- MojoMediaApplication
- Connection to services hosted in MojoMediaApplication through
  MojoShellContext.

This CL also fixes a bug in MojoCdm where the decryptor_ptr is bound to
one thread but is used on another thread.

BUG=581893
TEST=This CL adds a new test. No other functionality change.

Review-Url: https://codereview.chromium.org/2268283003
Cr-Commit-Position: refs/heads/master@{#420500}
parent 70e44d10
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "components/cdm/renderer/external_clear_key_key_system_properties.h"
#include "components/cdm/renderer/widevine_key_system_properties.h" #include "components/cdm/renderer/widevine_key_system_properties.h"
#include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_thread.h"
#include "media/base/eme_constants.h" #include "media/base/eme_constants.h"
...@@ -42,9 +43,6 @@ using media::KeySystemProperties; ...@@ -42,9 +43,6 @@ using media::KeySystemProperties;
using media::SupportedCodecs; using media::SupportedCodecs;
#if defined(ENABLE_PEPPER_CDMS) #if defined(ENABLE_PEPPER_CDMS)
static const char kExternalClearKeyPepperType[] =
"application/x-ppapi-clearkey-cdm";
static bool IsPepperCdmAvailable( static bool IsPepperCdmAvailable(
const std::string& pepper_type, const std::string& pepper_type,
std::vector<base::string16>* additional_param_names, std::vector<base::string16>* additional_param_names,
...@@ -60,76 +58,6 @@ static bool IsPepperCdmAvailable( ...@@ -60,76 +58,6 @@ static bool IsPepperCdmAvailable(
return is_available; return is_available;
} }
// KeySystemProperties implementation for external Clear Key systems.
class ExternalClearKeyProperties : public KeySystemProperties {
public:
explicit ExternalClearKeyProperties(const std::string& key_system_name)
: key_system_name_(key_system_name) {}
std::string GetKeySystemName() const override { return key_system_name_; }
bool IsSupportedInitDataType(
media::EmeInitDataType init_data_type) const override {
switch (init_data_type) {
case media::EmeInitDataType::WEBM:
case media::EmeInitDataType::KEYIDS:
return true;
case media::EmeInitDataType::CENC:
#if defined(USE_PROPRIETARY_CODECS)
return true;
#else
return false;
#endif // defined(USE_PROPRIETARY_CODECS)
case media::EmeInitDataType::UNKNOWN:
return false;
}
NOTREACHED();
return false;
}
SupportedCodecs GetSupportedCodecs() const override {
#if defined(USE_PROPRIETARY_CODECS)
return media::EME_CODEC_MP4_ALL | media::EME_CODEC_WEBM_ALL;
#else
return media::EME_CODEC_WEBM_ALL;
#endif
}
media::EmeConfigRule GetRobustnessConfigRule(
media::EmeMediaType media_type,
const std::string& requested_robustness) const override {
return requested_robustness.empty() ? media::EmeConfigRule::SUPPORTED
: media::EmeConfigRule::NOT_SUPPORTED;
}
// Persistent license sessions are faked.
media::EmeSessionTypeSupport GetPersistentLicenseSessionSupport()
const override {
return media::EmeSessionTypeSupport::SUPPORTED;
}
media::EmeSessionTypeSupport GetPersistentReleaseMessageSessionSupport()
const override {
return media::EmeSessionTypeSupport::NOT_SUPPORTED;
}
media::EmeFeatureSupport GetPersistentStateSupport() const override {
return media::EmeFeatureSupport::REQUESTABLE;
}
media::EmeFeatureSupport GetDistinctiveIdentifierSupport() const override {
return media::EmeFeatureSupport::NOT_SUPPORTED;
}
std::string GetPepperType() const override {
return kExternalClearKeyPepperType;
}
private:
const std::string key_system_name_;
};
// External Clear Key (used for testing). // External Clear Key (used for testing).
static void AddExternalClearKey( static void AddExternalClearKey(
std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) { std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) {
...@@ -150,40 +78,40 @@ static void AddExternalClearKey( ...@@ -150,40 +78,40 @@ static void AddExternalClearKey(
std::vector<base::string16> additional_param_names; std::vector<base::string16> additional_param_names;
std::vector<base::string16> additional_param_values; std::vector<base::string16> additional_param_values;
if (!IsPepperCdmAvailable(kExternalClearKeyPepperType, if (!IsPepperCdmAvailable(cdm::kExternalClearKeyPepperType,
&additional_param_names, &additional_param_names,
&additional_param_values)) { &additional_param_values)) {
return; return;
} }
concrete_key_systems->emplace_back( concrete_key_systems->emplace_back(
new ExternalClearKeyProperties(kExternalClearKeyKeySystem)); new cdm::ExternalClearKeyProperties(kExternalClearKeyKeySystem));
// Add support of decrypt-only mode in ClearKeyCdm. // Add support of decrypt-only mode in ClearKeyCdm.
concrete_key_systems->emplace_back( concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
new ExternalClearKeyProperties(kExternalClearKeyDecryptOnlyKeySystem)); kExternalClearKeyDecryptOnlyKeySystem));
// A key system that triggers renewal message in ClearKeyCdm. // A key system that triggers renewal message in ClearKeyCdm.
concrete_key_systems->emplace_back( concrete_key_systems->emplace_back(
new ExternalClearKeyProperties(kExternalClearKeyRenewalKeySystem)); new cdm::ExternalClearKeyProperties(kExternalClearKeyRenewalKeySystem));
// A key system that triggers the FileIO test in ClearKeyCdm. // A key system that triggers the FileIO test in ClearKeyCdm.
concrete_key_systems->emplace_back( concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
new ExternalClearKeyProperties(kExternalClearKeyFileIOTestKeySystem)); kExternalClearKeyFileIOTestKeySystem));
// A key system that triggers the output protection test in ClearKeyCdm. // A key system that triggers the output protection test in ClearKeyCdm.
concrete_key_systems->emplace_back(new ExternalClearKeyProperties( concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
kExternalClearKeyOutputProtectionTestKeySystem)); kExternalClearKeyOutputProtectionTestKeySystem));
// A key system that Chrome thinks is supported by ClearKeyCdm, but actually // A key system that Chrome thinks is supported by ClearKeyCdm, but actually
// will be refused by ClearKeyCdm. This is to test the CDM initialization // will be refused by ClearKeyCdm. This is to test the CDM initialization
// failure case. // failure case.
concrete_key_systems->emplace_back( concrete_key_systems->emplace_back(new cdm::ExternalClearKeyProperties(
new ExternalClearKeyProperties(kExternalClearKeyInitializeFailKeySystem)); kExternalClearKeyInitializeFailKeySystem));
// A key system that triggers a crash in ClearKeyCdm. // A key system that triggers a crash in ClearKeyCdm.
concrete_key_systems->emplace_back( concrete_key_systems->emplace_back(
new ExternalClearKeyProperties(kExternalClearKeyCrashKeySystem)); new cdm::ExternalClearKeyProperties(kExternalClearKeyCrashKeySystem));
} }
#if defined(WIDEVINE_CDM_AVAILABLE) #if defined(WIDEVINE_CDM_AVAILABLE)
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
static_library("renderer") { static_library("renderer") {
sources = [ sources = [
"external_clear_key_key_system_properties.cc",
"external_clear_key_key_system_properties.h",
"widevine_key_system_properties.cc", "widevine_key_system_properties.cc",
"widevine_key_system_properties.h", "widevine_key_system_properties.h",
] ]
......
...@@ -91,9 +91,7 @@ class AndroidPlatformKeySystemProperties : public KeySystemProperties { ...@@ -91,9 +91,7 @@ class AndroidPlatformKeySystemProperties : public KeySystemProperties {
const SupportedCodecs supported_codecs_; const SupportedCodecs supported_codecs_;
}; };
} // namespace SupportedKeySystemResponse QueryKeySystemSupport(
static SupportedKeySystemResponse QueryKeySystemSupport(
const std::string& key_system) { const std::string& key_system) {
SupportedKeySystemRequest request; SupportedKeySystemRequest request;
SupportedKeySystemResponse response; SupportedKeySystemResponse response;
...@@ -109,6 +107,8 @@ static SupportedKeySystemResponse QueryKeySystemSupport( ...@@ -109,6 +107,8 @@ static SupportedKeySystemResponse QueryKeySystemSupport(
return response; return response;
} }
} // namespace
void AddAndroidWidevine( void AddAndroidWidevine(
std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) { std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) {
SupportedKeySystemResponse response = QueryKeySystemSupport( SupportedKeySystemResponse response = QueryKeySystemSupport(
......
// Copyright 2016 The Chromium Authors. 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/renderer/external_clear_key_key_system_properties.h"
#include "base/logging.h"
#include "media/base/eme_constants.h"
namespace cdm {
#if defined(ENABLE_PEPPER_CDMS)
const char kExternalClearKeyPepperType[] = "application/x-ppapi-clearkey-cdm";
#endif
ExternalClearKeyProperties::ExternalClearKeyProperties(
const std::string& key_system_name)
: key_system_name_(key_system_name) {}
ExternalClearKeyProperties::~ExternalClearKeyProperties() {}
std::string ExternalClearKeyProperties::GetKeySystemName() const {
return key_system_name_;
}
bool ExternalClearKeyProperties::IsSupportedInitDataType(
media::EmeInitDataType init_data_type) const {
switch (init_data_type) {
case media::EmeInitDataType::WEBM:
case media::EmeInitDataType::KEYIDS:
return true;
case media::EmeInitDataType::CENC:
#if defined(USE_PROPRIETARY_CODECS)
return true;
#else
return false;
#endif // defined(USE_PROPRIETARY_CODECS)
case media::EmeInitDataType::UNKNOWN:
return false;
}
NOTREACHED();
return false;
}
media::SupportedCodecs ExternalClearKeyProperties::GetSupportedCodecs() const {
#if defined(USE_PROPRIETARY_CODECS)
return media::EME_CODEC_MP4_ALL | media::EME_CODEC_WEBM_ALL;
#else
return media::EME_CODEC_WEBM_ALL;
#endif
}
media::EmeConfigRule ExternalClearKeyProperties::GetRobustnessConfigRule(
media::EmeMediaType media_type,
const std::string& requested_robustness) const {
return requested_robustness.empty() ? media::EmeConfigRule::SUPPORTED
: media::EmeConfigRule::NOT_SUPPORTED;
}
// Persistent license sessions are faked.
media::EmeSessionTypeSupport
ExternalClearKeyProperties::GetPersistentLicenseSessionSupport() const {
return media::EmeSessionTypeSupport::SUPPORTED;
}
media::EmeSessionTypeSupport
ExternalClearKeyProperties::GetPersistentReleaseMessageSessionSupport() const {
return media::EmeSessionTypeSupport::NOT_SUPPORTED;
}
media::EmeFeatureSupport ExternalClearKeyProperties::GetPersistentStateSupport()
const {
return media::EmeFeatureSupport::REQUESTABLE;
}
media::EmeFeatureSupport
ExternalClearKeyProperties::GetDistinctiveIdentifierSupport() const {
return media::EmeFeatureSupport::NOT_SUPPORTED;
}
#if defined(ENABLE_PEPPER_CDMS)
std::string ExternalClearKeyProperties::GetPepperType() const {
return kExternalClearKeyPepperType;
}
#endif
} // namespace cdm
// Copyright 2016 The Chromium Authors. 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_RENDERER_EXTERNAL_CLEAR_KEY_KEY_SYSTEM_PROPERTIES_H_
#define COMPONENTS_CDM_RENDERER_EXTERNAL_CLEAR_KEY_KEY_SYSTEM_PROPERTIES_H_
#include <string>
#include "build/build_config.h"
#include "media/base/key_system_properties.h"
namespace cdm {
#if defined(ENABLE_PEPPER_CDMS)
extern const char kExternalClearKeyPepperType[];
#endif
// KeySystemProperties implementation for external Clear Key key systems.
class ExternalClearKeyProperties : public media::KeySystemProperties {
public:
explicit ExternalClearKeyProperties(const std::string& key_system_name);
~ExternalClearKeyProperties() override;
std::string GetKeySystemName() const override;
bool IsSupportedInitDataType(
media::EmeInitDataType init_data_type) const override;
media::SupportedCodecs GetSupportedCodecs() const override;
media::EmeConfigRule GetRobustnessConfigRule(
media::EmeMediaType media_type,
const std::string& requested_robustness) const override;
media::EmeSessionTypeSupport GetPersistentLicenseSessionSupport()
const override;
media::EmeSessionTypeSupport GetPersistentReleaseMessageSessionSupport()
const override;
media::EmeFeatureSupport GetPersistentStateSupport() const override;
media::EmeFeatureSupport GetDistinctiveIdentifierSupport() const override;
#if defined(ENABLE_PEPPER_CDMS)
std::string GetPepperType() const override;
#endif
private:
const std::string key_system_name_;
};
} // namespace cdm
#endif // COMPONENTS_CDM_RENDERER_EXTERNAL_CLEAR_KEY_KEY_SYSTEM_PROPERTIES_H_
...@@ -10,9 +10,11 @@ ...@@ -10,9 +10,11 @@
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/shell/browser/shell.h" #include "content/shell/browser/shell.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "base/android/build_info.h" #include "base/android/build_info.h"
#include "media/base/media.h" #include "media/base/media.h"
#include "media/base/media_switches.h"
#endif #endif
#if defined(ENABLE_MOJO_RENDERER) #if defined(ENABLE_MOJO_RENDERER)
...@@ -24,6 +26,10 @@ ...@@ -24,6 +26,10 @@
// Available key systems. // Available key systems.
const char kClearKeyKeySystem[] = "org.w3.clearkey"; const char kClearKeyKeySystem[] = "org.w3.clearkey";
#if defined(OS_ANDROID)
const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey";
#endif
// Supported media types. // Supported media types.
const char kWebMVorbisAudioOnly[] = "audio/webm; codecs=\"vorbis\""; const char kWebMVorbisAudioOnly[] = "audio/webm; codecs=\"vorbis\"";
#if !defined(DISABLE_ENCRYPTED_MEDIA_PLAYBACK_TESTS) #if !defined(DISABLE_ENCRYPTED_MEDIA_PLAYBACK_TESTS)
...@@ -60,7 +66,9 @@ static bool IsMSESupported() { ...@@ -60,7 +66,9 @@ static bool IsMSESupported() {
// Tests encrypted media playback with a combination of parameters: // Tests encrypted media playback with a combination of parameters:
// - char*: Key system name. // - char*: Key system name.
// - bool: True to load media using MSE, otherwise use src. // - SrcType: The type of video src used to load media, MSE or SRC.
// It is okay to run this test as a non-parameterized test, in this case,
// GetParam() should not be called.
class EncryptedMediaTest : public content::MediaBrowserTest, class EncryptedMediaTest : public content::MediaBrowserTest,
public testing::WithParamInterface<std::tr1::tuple<const char*, SrcType> > { public testing::WithParamInterface<std::tr1::tuple<const char*, SrcType> > {
public: public:
...@@ -142,6 +150,10 @@ class EncryptedMediaTest : public content::MediaBrowserTest, ...@@ -142,6 +150,10 @@ class EncryptedMediaTest : public content::MediaBrowserTest,
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch( command_line->AppendSwitch(
switches::kDisableGestureRequirementForMediaPlayback); switches::kDisableGestureRequirementForMediaPlayback);
#if defined(OS_ANDROID)
command_line->AppendSwitchASCII(switches::kEnableFeatures,
media::kExternalClearKeyForTesting.name);
#endif
} }
}; };
...@@ -215,4 +227,16 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, UnknownKeySystemThrowsException) { ...@@ -215,4 +227,16 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, UnknownKeySystemThrowsException) {
kEmeNotSupportedError); kEmeNotSupportedError);
} }
#if defined(OS_ANDROID)
// On Android, External Clear Key is supported in //content/shell/ by using mojo
// CDM with AesDecryptor running in the GPU process.
// On other platforms, External Clear Key is supported in chrome/, so it is
// tested in browser_tests.
IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, ExternalClearKeyPlayback) {
RunSimpleEncryptedMediaTest("bear-320x240-av_enc-av.webm",
kWebMVorbisAudioVP8Video,
kExternalClearKeyKeySystem, MSE);
}
#endif
} // namespace content } // namespace content
...@@ -220,6 +220,7 @@ static_library("content_shell_lib") { ...@@ -220,6 +220,7 @@ static_library("content_shell_lib") {
"//base:base_static", "//base:base_static",
"//base/third_party/dynamic_annotations", "//base/third_party/dynamic_annotations",
"//cc", "//cc",
"//components/cdm/renderer",
"//components/crash/content/app:app_breakpad_mac_win_to_be_deleted", "//components/crash/content/app:app_breakpad_mac_win_to_be_deleted",
"//components/plugins/renderer", "//components/plugins/renderer",
"//components/test_runner:test_runner", "//components/test_runner:test_runner",
......
include_rules = [ include_rules = [
"+gin", "+gin",
"+components/cdm",
"+components/web_cache/renderer", "+components/web_cache/renderer",
"+components/plugins/renderer", "+components/plugins/renderer",
"+components/test_runner", "+components/test_runner",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "components/cdm/renderer/external_clear_key_key_system_properties.h"
#include "components/web_cache/renderer/web_cache_impl.h" #include "components/web_cache/renderer/web_cache_impl.h"
#include "content/public/test/test_mojo_service.mojom.h" #include "content/public/test/test_mojo_service.mojom.h"
#include "content/shell/common/shell_switches.h" #include "content/shell/common/shell_switches.h"
...@@ -25,6 +26,11 @@ ...@@ -25,6 +26,11 @@
#include "ppapi/shared_impl/ppapi_switches.h" #include "ppapi/shared_impl/ppapi_switches.h"
#endif #endif
#if defined(OS_ANDROID)
#include "base/feature_list.h"
#include "media/base/media_switches.h"
#endif
namespace content { namespace content {
namespace { namespace {
...@@ -134,4 +140,17 @@ void ShellContentRendererClient::ExposeInterfacesToBrowser( ...@@ -134,4 +140,17 @@ void ShellContentRendererClient::ExposeInterfacesToBrowser(
base::Bind(&CreateTestMojoService)); base::Bind(&CreateTestMojoService));
} }
#if defined(OS_ANDROID)
void ShellContentRendererClient::AddSupportedKeySystems(
std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems) {
if (!base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting))
return;
static const char kExternalClearKeyKeySystem[] =
"org.chromium.externalclearkey";
key_systems->emplace_back(
new cdm::ExternalClearKeyProperties(kExternalClearKeyKeySystem));
}
#endif
} // namespace content } // namespace content
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "build/build_config.h"
#include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/content_renderer_client.h"
namespace web_cache { namespace web_cache {
...@@ -36,6 +37,12 @@ class ShellContentRendererClient : public ContentRendererClient { ...@@ -36,6 +37,12 @@ class ShellContentRendererClient : public ContentRendererClient {
void ExposeInterfacesToBrowser( void ExposeInterfacesToBrowser(
shell::InterfaceRegistry* interface_registry) override; shell::InterfaceRegistry* interface_registry) override;
#if defined(OS_ANDROID)
void AddSupportedKeySystems(
std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems)
override;
#endif
private: private:
std::unique_ptr<web_cache::WebCacheImpl> web_cache_impl_; std::unique_ptr<web_cache::WebCacheImpl> web_cache_impl_;
}; };
......
...@@ -4,11 +4,15 @@ ...@@ -4,11 +4,15 @@
#include "media/base/android/android_cdm_factory.h" #include "media/base/android/android_cdm_factory.h"
#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "media/base/android/media_drm_bridge.h" #include "media/base/android/media_drm_bridge.h"
#include "media/base/bind_to_current_loop.h" #include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_config.h" #include "media/base/cdm_config.h"
#include "media/base/key_system_names.h"
#include "media/base/key_systems.h" #include "media/base/key_systems.h"
#include "media/base/media_switches.h"
#include "media/cdm/aes_decryptor.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h" #include "third_party/widevine/cdm/widevine_cdm_common.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -36,6 +40,17 @@ void AndroidCdmFactory::Create( ...@@ -36,6 +40,17 @@ void AndroidCdmFactory::Create(
return; return;
} }
// Create AesDecryptor here to support External Clear Key key system.
// This is used for testing.
if (base::FeatureList::IsEnabled(media::kExternalClearKeyForTesting) &&
IsExternalClearKey(key_system)) {
scoped_refptr<MediaKeys> cdm(
new AesDecryptor(security_origin, session_message_cb, session_closed_cb,
session_keys_change_cb));
bound_cdm_created_cb.Run(cdm, "");
return;
}
std::string error_message; std::string error_message;
if (!MediaDrmBridge::IsKeySystemSupported(key_system)) { if (!MediaDrmBridge::IsKeySystemSupported(key_system)) {
......
...@@ -410,14 +410,19 @@ void KeySystemsImpl::AddSupportedKeySystems( ...@@ -410,14 +410,19 @@ void KeySystemsImpl::AddSupportedKeySystems(
// Distinctive identifiers and persistent state can only be reliably blocked // Distinctive identifiers and persistent state can only be reliably blocked
// (and therefore be safely configurable) for Pepper-hosted key systems. For // (and therefore be safely configurable) for Pepper-hosted key systems. For
// other platforms, (except for the AES decryptor) assume that the CDM can // other platforms assume the CDM can and will do anything, except for the
// and will do anything. // following two cases:
// 1) AES decryptor, and
// 2) External Clear Key key system on Android, only enabled for testing.
bool can_block = properties->UseAesDecryptor(); bool can_block = properties->UseAesDecryptor();
#if defined(ENABLE_PEPPER_CDMS) #if defined(ENABLE_PEPPER_CDMS)
DCHECK_EQ(properties->UseAesDecryptor(), DCHECK_EQ(properties->UseAesDecryptor(),
properties->GetPepperType().empty()); properties->GetPepperType().empty());
if (!properties->GetPepperType().empty()) if (!properties->GetPepperType().empty())
can_block = true; can_block = true;
#elif defined(OS_ANDROID)
if (IsExternalClearKey(properties->GetKeySystemName()))
can_block = true;
#endif #endif
if (!can_block) { if (!can_block) {
DCHECK(properties->GetDistinctiveIdentifierSupport() == DCHECK(properties->GetDistinctiveIdentifierSupport() ==
......
...@@ -84,8 +84,8 @@ MojoCdm::~MojoCdm() { ...@@ -84,8 +84,8 @@ MojoCdm::~MojoCdm() {
base::AutoLock auto_lock(lock_); base::AutoLock auto_lock(lock_);
// Release |decryptor_| on the correct thread. If GetDecryptor() is never // Release |decryptor_| on the correct thread. If GetDecryptor() is never
// called but |decryptor_ptr_| is not null, it is not bound to any thread and // called but |decryptor_ptr_info_| is not null, it is not bound to any thread
// is safe to be released on the current thread. // and is safe to be released on the current thread.
if (decryptor_task_runner_ && if (decryptor_task_runner_ &&
!decryptor_task_runner_->BelongsToCurrentThread() && decryptor_) { !decryptor_task_runner_->BelongsToCurrentThread() && decryptor_) {
decryptor_task_runner_->DeleteSoon(FROM_HERE, decryptor_.release()); decryptor_task_runner_->DeleteSoon(FROM_HERE, decryptor_.release());
...@@ -219,9 +219,11 @@ media::Decryptor* MojoCdm::GetDecryptor() { ...@@ -219,9 +219,11 @@ media::Decryptor* MojoCdm::GetDecryptor() {
DCHECK(decryptor_task_runner_->BelongsToCurrentThread()); DCHECK(decryptor_task_runner_->BelongsToCurrentThread());
// Can be called on a different thread. // Can be called on a different thread.
if (decryptor_ptr_) { if (decryptor_ptr_info_.is_valid()) {
DCHECK(!decryptor_); DCHECK(!decryptor_);
decryptor_.reset(new MojoDecryptor(std::move(decryptor_ptr_))); mojom::DecryptorPtr decryptor_ptr;
decryptor_ptr.Bind(std::move(decryptor_ptr_info_));
decryptor_.reset(new MojoDecryptor(std::move(decryptor_ptr)));
} }
return decryptor_.get(); return decryptor_.get();
...@@ -306,7 +308,7 @@ void MojoCdm::OnCdmInitialized(mojom::CdmPromiseResultPtr result, ...@@ -306,7 +308,7 @@ void MojoCdm::OnCdmInitialized(mojom::CdmPromiseResultPtr result,
base::AutoLock auto_lock(lock_); base::AutoLock auto_lock(lock_);
DCHECK_NE(CdmContext::kInvalidCdmId, cdm_id); DCHECK_NE(CdmContext::kInvalidCdmId, cdm_id);
cdm_id_ = cdm_id; cdm_id_ = cdm_id;
decryptor_ptr_ = std::move(decryptor); decryptor_ptr_info_ = decryptor.PassInterface();
} }
pending_init_promise_->resolve(); pending_init_promise_->resolve();
......
...@@ -140,10 +140,10 @@ class MojoCdm : public MediaKeys, ...@@ -140,10 +140,10 @@ class MojoCdm : public MediaKeys,
// be invalid if initialization succeeded. // be invalid if initialization succeeded.
int cdm_id_; int cdm_id_;
// The DecryptorPtr exposed by the remote CDM. Set after initialization is // The DecryptorPtrInfo exposed by the remote CDM. Set after initialization
// completed and cleared after |decryptor_| is created. May be null after // is completed and cleared after |decryptor_| is created. May be invalid
// initialization if the CDM doesn't support a Decryptor. // after initialization if the CDM doesn't support a Decryptor.
mojom::DecryptorPtr decryptor_ptr_; mojom::DecryptorPtrInfo decryptor_ptr_info_;
// Decryptor based on |decryptor_ptr_|, lazily created in GetDecryptor(). // Decryptor based on |decryptor_ptr_|, lazily created in GetDecryptor().
// Since GetDecryptor() can be called on a different thread, use // Since GetDecryptor() can be called on a different thread, use
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment