diff options
22 files changed, 245 insertions, 363 deletions
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 4e1ba18..bb9b317 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc @@ -45,7 +45,6 @@ #include "gpu/command_buffer/service/gpu_switches.h" #include "media/audio/audio_manager.h" #include "media/audio/audio_manager_factory.h" -#include "media/base/browser_cdm_factory.h" #include "media/base/media.h" #include "ui/compositor/compositor_switches.h" @@ -311,12 +310,6 @@ void CastBrowserMainParts::PreMainMessageLoopRun() { const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); #if defined(OS_ANDROID) ::media::SetMediaClientAndroid(new media::CastMediaClientAndroid()); -#else - if (cmd_line->HasSwitch(switches::kEnableCmaMediaPipeline)) { - scoped_ptr<::media::BrowserCdmFactory> cdm_factory = - cast_browser_process_->browser_client()->CreateBrowserCdmFactory(); - ::media::SetBrowserCdmFactory(cdm_factory.release()); - } #endif // defined(OS_ANDROID) cast_browser_process_->SetConnectivityChecker( diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 14ff5c2..49294bd 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc @@ -90,11 +90,6 @@ scoped_refptr<media::CmaMediaPipelineClient> CastContentBrowserClient::CreateCmaMediaPipelineClient() { return make_scoped_refptr(new media::CmaMediaPipelineClient()); } - -scoped_ptr<::media::BrowserCdmFactory> -CastContentBrowserClient::CreateBrowserCdmFactory() { - return make_scoped_ptr(new media::CastBrowserCdmFactory()); -} #endif // OS_ANDROID void CastContentBrowserClient::ProcessExiting() { @@ -364,6 +359,7 @@ void CastContentBrowserClient::RegisterUnsandboxedOutOfProcessMojoApplications( } #if defined(OS_ANDROID) + void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line, int child_process_id, @@ -389,7 +385,18 @@ void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess( } } } + #else + +scoped_ptr<::media::CdmFactory> CastContentBrowserClient::CreateCdmFactory() { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableCmaMediaPipeline)) { + return make_scoped_ptr(new media::CastBrowserCdmFactory()); + } + + return nullptr; +} + void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line, int child_process_id, @@ -399,6 +406,7 @@ void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess( mappings->Share(kCrashDumpSignal, crash_signal_fd); } } + #endif // defined(OS_ANDROID) #if defined(OS_ANDROID) && defined(VIDEO_HOLE) diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 11763b8b..12129e3 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h @@ -71,10 +71,6 @@ class CastContentBrowserClient : public content::ContentBrowserClient { // instance. virtual scoped_refptr<media::CmaMediaPipelineClient> CreateCmaMediaPipelineClient(); - - // Creates and returns a factory used for creating BrowserCdm instances for - // playing protected content. This is called once per browser lifetime. - virtual scoped_ptr<::media::BrowserCdmFactory> CreateBrowserCdmFactory(); #endif // Performs cleanup for process exit (but before AtExitManager cleanup). @@ -150,6 +146,7 @@ class CastContentBrowserClient : public content::ContentBrowserClient { content::FileDescriptorInfo* mappings, std::map<int, base::MemoryMappedFile::Region>* regions) override; #else + scoped_ptr<::media::CdmFactory> CreateCdmFactory() override; void GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line, int child_process_id, diff --git a/chromecast/browser/media/cast_browser_cdm_factory.cc b/chromecast/browser/media/cast_browser_cdm_factory.cc index e93927b..c657a69 100644 --- a/chromecast/browser/media/cast_browser_cdm_factory.cc +++ b/chromecast/browser/media/cast_browser_cdm_factory.cc @@ -10,51 +10,60 @@ #include "chromecast/media/base/media_message_loop.h" #include "chromecast/media/cdm/browser_cdm_cast.h" #include "media/base/bind_to_current_loop.h" +#include "media/base/cdm_config.h" #include "media/base/cdm_key_information.h" namespace chromecast { namespace media { -scoped_refptr<::media::MediaKeys> CastBrowserCdmFactory::CreateBrowserCdm( - const std::string& key_system_name, - bool use_hw_secure_codecs, +void CastBrowserCdmFactory::Create( + const std::string& key_system, + const GURL& security_origin, + const ::media::CdmConfig& cdm_config, const ::media::SessionMessageCB& session_message_cb, const ::media::SessionClosedCB& session_closed_cb, const ::media::LegacySessionErrorCB& legacy_session_error_cb, const ::media::SessionKeysChangeCB& session_keys_change_cb, - const ::media::SessionExpirationUpdateCB& session_expiration_update_cb) { - DCHECK(!use_hw_secure_codecs) + const ::media::SessionExpirationUpdateCB& session_expiration_update_cb, + const ::media::CdmCreatedCB& cdm_created_cb) { + // Bound |cdm_created_cb| so we always fire it asynchronously. + ::media::CdmCreatedCB bound_cdm_created_cb = + ::media::BindToCurrentLoop(cdm_created_cb); + + DCHECK(!cdm_config.use_hw_secure_codecs) << "Chromecast does not use |use_hw_secure_codecs|"; - CastKeySystem key_system(GetKeySystemByName(key_system_name)); + CastKeySystem cast_key_system(GetKeySystemByName(key_system)); scoped_refptr<chromecast::media::BrowserCdmCast> browser_cdm; - if (key_system == chromecast::media::KEY_SYSTEM_CLEAR_KEY) { + if (cast_key_system == chromecast::media::KEY_SYSTEM_CLEAR_KEY) { // TODO(gunsch): handle ClearKey decryption. See crbug.com/441957 } else { - browser_cdm = CreatePlatformBrowserCdm(key_system); + browser_cdm = CreatePlatformBrowserCdm(cast_key_system); } - if (browser_cdm) { - MediaMessageLoop::GetTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&BrowserCdmCast::Initialize, - base::Unretained(browser_cdm.get()), - ::media::BindToCurrentLoop(session_message_cb), - ::media::BindToCurrentLoop(session_closed_cb), - ::media::BindToCurrentLoop(legacy_session_error_cb), - ::media::BindToCurrentLoop(session_keys_change_cb), - ::media::BindToCurrentLoop(session_expiration_update_cb))); - return scoped_refptr<::media::MediaKeys>( - new BrowserCdmCastUi(browser_cdm, MediaMessageLoop::GetTaskRunner())); + if (!browser_cdm) { + LOG(INFO) << "No matching key system found: " << cast_key_system; + bound_cdm_created_cb.Run(nullptr, "No matching key system found."); + return; } - LOG(INFO) << "No matching key system found."; - return nullptr; + MediaMessageLoop::GetTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&BrowserCdmCast::Initialize, + base::Unretained(browser_cdm.get()), + ::media::BindToCurrentLoop(session_message_cb), + ::media::BindToCurrentLoop(session_closed_cb), + ::media::BindToCurrentLoop(legacy_session_error_cb), + ::media::BindToCurrentLoop(session_keys_change_cb), + ::media::BindToCurrentLoop(session_expiration_update_cb))); + + bound_cdm_created_cb.Run( + new BrowserCdmCastUi(browser_cdm, MediaMessageLoop::GetTaskRunner()), ""); } scoped_refptr<BrowserCdmCast> CastBrowserCdmFactory::CreatePlatformBrowserCdm( - const CastKeySystem& key_system) { + const CastKeySystem& cast_key_system) { return nullptr; } diff --git a/chromecast/browser/media/cast_browser_cdm_factory.h b/chromecast/browser/media/cast_browser_cdm_factory.h index c55b8fa..22c31bc 100644 --- a/chromecast/browser/media/cast_browser_cdm_factory.h +++ b/chromecast/browser/media/cast_browser_cdm_factory.h @@ -6,7 +6,7 @@ #define CHROMECAST_BROWSER_MEDIA_CAST_BROWSER_CDM_FACTORY_H_ #include "chromecast/media/base/key_systems_common.h" -#include "media/base/browser_cdm_factory.h" +#include "media/base/cdm_factory.h" #include "media/base/media_keys.h" namespace chromecast { @@ -14,25 +14,26 @@ namespace media { class BrowserCdmCast; -class CastBrowserCdmFactory : public ::media::BrowserCdmFactory { +class CastBrowserCdmFactory : public ::media::CdmFactory { public: CastBrowserCdmFactory() {} ~CastBrowserCdmFactory() override {}; - // ::media::BrowserCdmFactory implementation: - scoped_refptr<::media::MediaKeys> CreateBrowserCdm( + // ::media::CdmFactory implementation: + void Create( const std::string& key_system, - bool use_hw_secure_codecs, + const GURL& security_origin, + const ::media::CdmConfig& cdm_config, const ::media::SessionMessageCB& session_message_cb, const ::media::SessionClosedCB& session_closed_cb, const ::media::LegacySessionErrorCB& legacy_session_error_cb, const ::media::SessionKeysChangeCB& session_keys_change_cb, - const ::media::SessionExpirationUpdateCB& session_expiration_update_cb) - override; + const ::media::SessionExpirationUpdateCB& session_expiration_update_cb, + const ::media::CdmCreatedCB& cdm_created_cb) override; // Provides a platform-specific BrowserCdm instance. virtual scoped_refptr<BrowserCdmCast> CreatePlatformBrowserCdm( - const CastKeySystem& key_system); + const CastKeySystem& cast_key_system); private: DISALLOW_COPY_AND_ASSIGN(CastBrowserCdmFactory); diff --git a/content/browser/media/cdm/browser_cdm_manager.cc b/content/browser/media/cdm/browser_cdm_manager.cc index 6ba327b..1b7f552 100644 --- a/content/browser/media/cdm/browser_cdm_manager.cc +++ b/content/browser/media/cdm/browser_cdm_manager.cc @@ -7,6 +7,7 @@ #include <string> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/lazy_instance.h" #include "base/memory/scoped_ptr.h" #include "base/task_runner.h" @@ -19,12 +20,14 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/web_contents.h" -#include "media/base/browser_cdm_factory.h" +#include "media/base/cdm_config.h" +#include "media/base/cdm_factory.h" #include "media/base/cdm_promise.h" #include "media/base/limits.h" #if defined(OS_ANDROID) #include "content/public/common/renderer_preferences.h" +#include "media/base/android/android_cdm_factory.h" #endif namespace content { @@ -269,6 +272,20 @@ void BrowserCdmManager::RejectPromise(int render_frame_id, system_code, error_message)); } +media::CdmFactory* BrowserCdmManager::GetCdmFactory() { + if (!cdm_factory_) { + // Create a new CdmFactory. + cdm_factory_ = GetContentClient()->browser()->CreateCdmFactory(); + +#if defined(OS_ANDROID) + if (!cdm_factory_) + cdm_factory_.reset(new media::AndroidCdmFactory()); +#endif + } + + return cdm_factory_.get(); +} + void BrowserCdmManager::OnSessionMessage(int render_frame_id, int cdm_id, const std::string& session_id, @@ -327,20 +344,52 @@ void BrowserCdmManager::OnSessionExpirationUpdate( new_expiry_time)); } +// Use a weak pointer here instead of |this| to avoid circular references. +#define BROWSER_CDM_MANAGER_CB(func, ...) \ + base::Bind(&BrowserCdmManager::func, weak_ptr_factory_.GetWeakPtr(), \ + render_frame_id, cdm_id, ##__VA_ARGS__) + void BrowserCdmManager::OnInitializeCdm( int render_frame_id, int cdm_id, uint32_t promise_id, const CdmHostMsg_InitializeCdm_Params& params) { + DCHECK(task_runner_->RunsTasksOnCurrentThread()); + DCHECK(!GetCdm(render_frame_id, cdm_id)); + + scoped_ptr<SimplePromise> promise(new SimplePromise( + weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id)); + if (params.key_system.size() > media::limits::kMaxKeySystemLength) { NOTREACHED() << "Invalid key system: " << params.key_system; - RejectPromise(render_frame_id, cdm_id, promise_id, - MediaKeys::INVALID_ACCESS_ERROR, 0, "Invalid key system."); + promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Invalid key system."); return; } - AddCdm(render_frame_id, cdm_id, promise_id, params.key_system, - params.security_origin, params.use_hw_secure_codecs); + if (!GetCdmFactory()) { + NOTREACHED() << "CDM not supported."; + promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "CDM not supported."); + return; + } + + // The render process makes sure |allow_distinctive_identifier| and + // |allow_persistent_state| are true. See RenderCdmFactory::Create(). + // TODO(xhwang): Pass |allow_distinctive_identifier| and + // |allow_persistent_state| from the render process. + media::CdmConfig cdm_config; + cdm_config.allow_distinctive_identifier = true; + cdm_config.allow_persistent_state = true; + cdm_config.use_hw_secure_codecs = params.use_hw_secure_codecs; + + GetCdmFactory()->Create( + params.key_system, params.security_origin, cdm_config, + BROWSER_CDM_MANAGER_CB(OnSessionMessage), + BROWSER_CDM_MANAGER_CB(OnSessionClosed), + BROWSER_CDM_MANAGER_CB(OnLegacySessionError), + BROWSER_CDM_MANAGER_CB(OnSessionKeysChange), + BROWSER_CDM_MANAGER_CB(OnSessionExpirationUpdate), + BROWSER_CDM_MANAGER_CB(OnCdmCreated, params.security_origin, + base::Passed(&promise))); } void BrowserCdmManager::OnSetServerCertificate( @@ -522,34 +571,16 @@ void BrowserCdmManager::OnDestroyCdm(int render_frame_id, int cdm_id) { RemoveCdm(GetId(render_frame_id, cdm_id)); } -// Use a weak pointer here instead of |this| to avoid circular references. -#define BROWSER_CDM_MANAGER_CB(func) \ - base::Bind(&BrowserCdmManager::func, weak_ptr_factory_.GetWeakPtr(), \ - render_frame_id, cdm_id) - -void BrowserCdmManager::AddCdm(int render_frame_id, - int cdm_id, - uint32_t promise_id, - const std::string& key_system, - const GURL& security_origin, - bool use_hw_secure_codecs) { - DCHECK(task_runner_->RunsTasksOnCurrentThread()); - DCHECK(!GetCdm(render_frame_id, cdm_id)); - - scoped_ptr<SimplePromise> promise(new SimplePromise( - weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id)); - - scoped_refptr<MediaKeys> cdm(media::CreateBrowserCdm( - key_system, use_hw_secure_codecs, - BROWSER_CDM_MANAGER_CB(OnSessionMessage), - BROWSER_CDM_MANAGER_CB(OnSessionClosed), - BROWSER_CDM_MANAGER_CB(OnLegacySessionError), - BROWSER_CDM_MANAGER_CB(OnSessionKeysChange), - BROWSER_CDM_MANAGER_CB(OnSessionExpirationUpdate))); - +void BrowserCdmManager::OnCdmCreated( + int render_frame_id, + int cdm_id, + const GURL& security_origin, + scoped_ptr<media::SimpleCdmPromise> promise, + const scoped_refptr<media::MediaKeys>& cdm, + const std::string& error_message) { if (!cdm) { - DVLOG(1) << "failed to create CDM."; - promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "Failed to create CDM."); + DVLOG(1) << "Failed to create CDM: " << error_message; + promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, error_message); return; } diff --git a/content/browser/media/cdm/browser_cdm_manager.h b/content/browser/media/cdm/browser_cdm_manager.h index fd2168d..521de14a 100644 --- a/content/browser/media/cdm/browser_cdm_manager.h +++ b/content/browser/media/cdm/browser_cdm_manager.h @@ -26,6 +26,10 @@ struct CdmHostMsg_CreateSessionAndGenerateRequest_Params; +namespace media { +class CdmFactory; +} + namespace content { // This class manages all CDM objects. It receives control operations from the @@ -79,6 +83,10 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter { ~BrowserCdmManager() override; private: + // Returns the CdmFactory that can be used to create CDMs. Returns null if + // CDM is not supported. + media::CdmFactory* GetCdmFactory(); + // CDM callbacks. void OnSessionMessage(int render_frame_id, int cdm_id, @@ -137,14 +145,13 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter { const std::string& session_id); void OnDestroyCdm(int render_frame_id, int cdm_id); - // Adds a new CDM identified by |cdm_id| for the given |key_system| and - // |security_origin|. - void AddCdm(int render_frame_id, - int cdm_id, - uint32_t promise_id, - const std::string& key_system, - const GURL& security_origin, - bool use_hw_secure_codecs); + // Callback for CDM creation. + void OnCdmCreated(int render_frame_id, + int cdm_id, + const GURL& security_origin, + scoped_ptr<media::SimpleCdmPromise> promise, + const scoped_refptr<media::MediaKeys>& cdm, + const std::string& error_message); // Removes all CDMs associated with |render_frame_id|. void RemoveAllCdmForFrame(int render_frame_id); @@ -193,6 +200,8 @@ class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter { // dispatched to the browser UI thread. scoped_refptr<base::TaskRunner> task_runner_; + scoped_ptr<media::CdmFactory> cdm_factory_; + // The key in the following maps is a combination of |render_frame_id| and // |cdm_id|. diff --git a/content/public/browser/DEPS b/content/public/browser/DEPS index ce66e26..d9b1c76 100644 --- a/content/public/browser/DEPS +++ b/content/public/browser/DEPS @@ -1,5 +1,6 @@ specific_include_rules = { ".*\.cc": [ "+content/browser", + "+media/base", # For CdmFactory. ], } diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 8f92ff3..3be2a8f 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc @@ -7,6 +7,7 @@ #include "base/files/file_path.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/common/sandbox_type.h" +#include "media/base/cdm_factory.h" #include "storage/browser/quota/quota_manager.h" #include "ui/gfx/image/image_skia.h" #include "url/gurl.h" @@ -113,6 +114,10 @@ bool ContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation( return false; } +scoped_ptr<media::CdmFactory> ContentBrowserClient::CreateCdmFactory() { + return nullptr; +} + bool ContentBrowserClient::ShouldSwapProcessesForRedirect( ResourceContext* resource_context, const GURL& current_url, const GURL& new_url) { diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index fe3538f..a4bad09 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -54,6 +54,10 @@ namespace gfx { class ImageSkia; } +namespace media { +class CdmFactory; +} + namespace mojo { class ApplicationDelegate; } @@ -709,6 +713,10 @@ class CONTENT_EXPORT ContentBrowserClient { virtual ScopedVector<NavigationThrottle> CreateThrottlesForNavigation( NavigationHandle* navigation_handle); + // Creates and returns a factory used for creating CDM instances for playing + // protected content. + virtual scoped_ptr<media::CdmFactory> CreateCdmFactory(); + // Populates |mappings| with all files that need to be mapped before launching // a child process. #if defined(OS_ANDROID) diff --git a/media/BUILD.gn b/media/BUILD.gn index a7dac69..71d6c4c 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -387,8 +387,6 @@ component("media") { "capture/video/android/video_capture_device_android.h", "capture/video/android/video_capture_device_factory_android.cc", "capture/video/android/video_capture_device_factory_android.h", - "cdm/android_cdm_factory.cc", - "cdm/android_cdm_factory.h", ] sources -= [ "filters/decrypting_audio_decoder.cc", diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index c6705a0..fba3fda 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn @@ -238,13 +238,6 @@ source_set("base") { deps += [ "//third_party/ffmpeg" ] } - if (enable_browser_cdms) { - sources += [ - "browser_cdm_factory.cc", - "browser_cdm_factory.h", - ] - } - if (is_android) { public_deps = [ "//media/base/android", diff --git a/media/base/android/BUILD.gn b/media/base/android/BUILD.gn index 65ce1fc..392d58f 100644 --- a/media/base/android/BUILD.gn +++ b/media/base/android/BUILD.gn @@ -14,10 +14,10 @@ source_set("android") { sources = [ "access_unit_queue.cc", "access_unit_queue.h", + "android_cdm_factory.cc", + "android_cdm_factory.h", "audio_decoder_job.cc", "audio_decoder_job.h", - "browser_cdm_factory_android.cc", - "browser_cdm_factory_android.h", "demuxer_android.h", "demuxer_stream_player_params.cc", "demuxer_stream_player_params.h", diff --git a/media/base/android/android_cdm_factory.cc b/media/base/android/android_cdm_factory.cc new file mode 100644 index 0000000..45bfad5 --- /dev/null +++ b/media/base/android/android_cdm_factory.cc @@ -0,0 +1,85 @@ +// Copyright 2015 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 "media/base/android/android_cdm_factory.h" + +#include "base/strings/string_number_conversions.h" +#include "media/base/android/media_drm_bridge.h" +#include "media/base/bind_to_current_loop.h" +#include "media/base/cdm_config.h" +#include "media/base/key_systems.h" +#include "third_party/widevine/cdm/widevine_cdm_common.h" +#include "url/gurl.h" + +namespace media { + +AndroidCdmFactory::AndroidCdmFactory() {} + +AndroidCdmFactory::~AndroidCdmFactory() {} + +void AndroidCdmFactory::Create( + const std::string& key_system, + const GURL& security_origin, + const CdmConfig& cdm_config, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const LegacySessionErrorCB& legacy_session_error_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb, + const CdmCreatedCB& cdm_created_cb) { + // Bound |cdm_created_cb| so we always fire it asynchronously. + CdmCreatedCB bound_cdm_created_cb = BindToCurrentLoop(cdm_created_cb); + + if (!security_origin.is_valid()) { + bound_cdm_created_cb.Run(nullptr, "Invalid origin."); + return; + } + + std::string error_message; + + if (!MediaDrmBridge::IsKeySystemSupported(key_system)) { + error_message = "Key system not supported unexpectedly: " + key_system; + NOTREACHED() << error_message; + bound_cdm_created_cb.Run(nullptr, error_message); + return; + } + + scoped_refptr<MediaDrmBridge> cdm( + MediaDrmBridge::Create(key_system, session_message_cb, session_closed_cb, + legacy_session_error_cb, session_keys_change_cb, + session_expiration_update_cb)); + if (!cdm) { + error_message = "MediaDrmBridge cannot be created for " + key_system; + NOTREACHED() << error_message; + bound_cdm_created_cb.Run(nullptr, error_message); + return; + } + + if (key_system == kWidevineKeySystem) { + MediaDrmBridge::SecurityLevel security_level = + cdm_config.use_hw_secure_codecs ? MediaDrmBridge::SECURITY_LEVEL_1 + : MediaDrmBridge::SECURITY_LEVEL_3; + if (!cdm->SetSecurityLevel(security_level)) { + error_message = + "failed to set security level " + base::IntToString(security_level); + DVLOG(1) << error_message; + bound_cdm_created_cb.Run(nullptr, error_message); + return; + } + } else if (!cdm_config.use_hw_secure_codecs) { + // Assume other key systems require hardware-secure codecs and thus do not + // support full compositing. + error_message = + key_system + + " may require use_video_overlay_for_embedded_encrypted_video"; + NOTREACHED() << error_message; + bound_cdm_created_cb.Run(nullptr, error_message); + return; + } + + // Success! + bound_cdm_created_cb.Run(cdm, ""); +} + +} // namespace media diff --git a/media/cdm/android_cdm_factory.h b/media/base/android/android_cdm_factory.h index b0ee4bb..c469af8 100644 --- a/media/cdm/android_cdm_factory.h +++ b/media/base/android/android_cdm_factory.h @@ -2,17 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MEDIA_CDM_ANDROID_CDM_FACTORY_H_ -#define MEDIA_CDM_ANDROID_CDM_FACTORY_H_ +#ifndef MEDIA_BASE_ANDROID_ANDROID_CDM_FACTORY_H_ +#define MEDIA_BASE_ANDROID_ANDROID_CDM_FACTORY_H_ #include "base/macros.h" #include "media/base/cdm_factory.h" +#include "media/base/media_export.h" namespace media { struct CdmConfig; -class AndroidCdmFactory : public CdmFactory { +class MEDIA_EXPORT AndroidCdmFactory : public CdmFactory { public: AndroidCdmFactory(); ~AndroidCdmFactory() final; @@ -34,4 +35,4 @@ class AndroidCdmFactory : public CdmFactory { } // namespace media -#endif // MEDIA_CDM_ANDROID_CDM_FACTORY_H_ +#endif // MEDIA_BASE_ANDROID_ANDROID_CDM_FACTORY_H_ diff --git a/media/base/android/browser_cdm_factory_android.cc b/media/base/android/browser_cdm_factory_android.cc deleted file mode 100644 index 9b43379..0000000 --- a/media/base/android/browser_cdm_factory_android.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 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 "media/base/android/browser_cdm_factory_android.h" - -#include "base/command_line.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "media/base/android/media_drm_bridge.h" -#include "media/base/media_switches.h" -#include "third_party/widevine/cdm/widevine_cdm_common.h" - -namespace media { - -scoped_refptr<MediaKeys> BrowserCdmFactoryAndroid::CreateBrowserCdm( - const std::string& key_system, - bool use_hw_secure_codecs, - const SessionMessageCB& session_message_cb, - const SessionClosedCB& session_closed_cb, - const LegacySessionErrorCB& legacy_session_error_cb, - const SessionKeysChangeCB& session_keys_change_cb, - const SessionExpirationUpdateCB& session_expiration_update_cb) { - if (!MediaDrmBridge::IsKeySystemSupported(key_system)) { - NOTREACHED() << "Key system not supported unexpectedly: " << key_system; - return nullptr; - } - - scoped_refptr<MediaDrmBridge> cdm( - MediaDrmBridge::Create(key_system, session_message_cb, session_closed_cb, - legacy_session_error_cb, session_keys_change_cb, - session_expiration_update_cb)); - if (!cdm) { - NOTREACHED() << "MediaDrmBridge cannot be created for " << key_system; - return nullptr; - } - - if (key_system == kWidevineKeySystem) { - MediaDrmBridge::SecurityLevel security_level = - use_hw_secure_codecs ? MediaDrmBridge::SECURITY_LEVEL_1 - : MediaDrmBridge::SECURITY_LEVEL_3; - if (!cdm->SetSecurityLevel(security_level)) { - DVLOG(1) << "failed to set security level " << security_level; - return nullptr; - } - } else { - // Assume other key systems require hardware-secure codecs and thus do not - // support full compositing. - if (!use_hw_secure_codecs) { - NOTREACHED() - << key_system - << " may require use_video_overlay_for_embedded_encrypted_video"; - return nullptr; - } - } - - return cdm; -} - -} // namespace media diff --git a/media/base/android/browser_cdm_factory_android.h b/media/base/android/browser_cdm_factory_android.h deleted file mode 100644 index babae75..0000000 --- a/media/base/android/browser_cdm_factory_android.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2014 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 MEDIA_BASE_BROWSER_CDM_FACTORY_ANDROID_H_ -#define MEDIA_BASE_BROWSER_CDM_FACTORY_ANDROID_H_ - -#include "base/macros.h" -#include "media/base/browser_cdm_factory.h" -#include "media/base/media_export.h" - -namespace media { - -class MEDIA_EXPORT BrowserCdmFactoryAndroid : public BrowserCdmFactory { - public: - BrowserCdmFactoryAndroid() {} - ~BrowserCdmFactoryAndroid() final {}; - - scoped_refptr<MediaKeys> CreateBrowserCdm( - const std::string& key_system, - bool use_hw_secure_codecs, - const SessionMessageCB& session_message_cb, - const SessionClosedCB& session_closed_cb, - const LegacySessionErrorCB& legacy_session_error_cb, - const SessionKeysChangeCB& session_keys_change_cb, - const SessionExpirationUpdateCB& session_expiration_update_cb) final; - - private: - DISALLOW_COPY_AND_ASSIGN(BrowserCdmFactoryAndroid); -}; - -} // namespace media - -#endif // MEDIA_BASE_BROWSER_CDM_FACTORY_ANDROID_H_ diff --git a/media/base/browser_cdm_factory.cc b/media/base/browser_cdm_factory.cc deleted file mode 100644 index 69a6a02..0000000 --- a/media/base/browser_cdm_factory.cc +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2014 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 "media/base/browser_cdm_factory.h" - -#include "base/logging.h" - -#if defined(OS_ANDROID) -#include "media/base/android/browser_cdm_factory_android.h" -#endif - -namespace media { - -namespace { -BrowserCdmFactory* g_cdm_factory = NULL; -} - -void SetBrowserCdmFactory(BrowserCdmFactory* factory) { - DCHECK(!g_cdm_factory); - g_cdm_factory = factory; -} - -scoped_refptr<MediaKeys> CreateBrowserCdm( - const std::string& key_system, - bool use_hw_secure_codecs, - const SessionMessageCB& session_message_cb, - const SessionClosedCB& session_closed_cb, - const LegacySessionErrorCB& legacy_session_error_cb, - const SessionKeysChangeCB& session_keys_change_cb, - const SessionExpirationUpdateCB& session_expiration_update_cb) { - if (!g_cdm_factory) { -#if defined(OS_ANDROID) - SetBrowserCdmFactory(new BrowserCdmFactoryAndroid()); -#else - LOG(ERROR) << "Cannot create BrowserCdm: no BrowserCdmFactory available!"; - return nullptr; -#endif - } - - return g_cdm_factory->CreateBrowserCdm( - key_system, use_hw_secure_codecs, session_message_cb, session_closed_cb, - legacy_session_error_cb, session_keys_change_cb, - session_expiration_update_cb); -} - -} // namespace media diff --git a/media/base/browser_cdm_factory.h b/media/base/browser_cdm_factory.h deleted file mode 100644 index 8a05a67..0000000 --- a/media/base/browser_cdm_factory.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 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 MEDIA_BASE_BROWSER_CDM_FACTORY_H_ -#define MEDIA_BASE_BROWSER_CDM_FACTORY_H_ - -#include <string> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "media/base/media_export.h" -#include "media/base/media_keys.h" - -namespace media { - -// TODO(xhwang): Merge this with media::CdmFactory. -class MEDIA_EXPORT BrowserCdmFactory { - public: - BrowserCdmFactory() {} - virtual ~BrowserCdmFactory() {} - - virtual scoped_refptr<MediaKeys> CreateBrowserCdm( - const std::string& key_system, - bool use_hw_secure_codecs, - const SessionMessageCB& session_message_cb, - const SessionClosedCB& session_closed_cb, - const LegacySessionErrorCB& legacy_session_error_cb, - const SessionKeysChangeCB& session_keys_change_cb, - const SessionExpirationUpdateCB& session_expiration_update_cb) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(BrowserCdmFactory); -}; - -// Provides a factory for creating BrowserCdm instances. There is only one -// BrowserCdmFactory per process. -void SetBrowserCdmFactory(BrowserCdmFactory* factory); - -// Creates a MediaKeys for |key_system|. Returns NULL if the CDM cannot be -// created. -// |use_hw_secure_codecs| indicates that the CDM should be configured to use -// hardware-secure codecs (for platforms that support it). -// TODO(xhwang): Add ifdef for IPC based CDM. -scoped_refptr<MediaKeys> MEDIA_EXPORT -CreateBrowserCdm(const std::string& key_system, - bool use_hw_secure_codecs, - const SessionMessageCB& session_message_cb, - const SessionClosedCB& session_closed_cb, - const LegacySessionErrorCB& legacy_session_error_cb, - const SessionKeysChangeCB& session_keys_change_cb, - const SessionExpirationUpdateCB& session_expiration_update_cb); - -} // namespace media - -#endif // MEDIA_BASE_BROWSER_CDM_FACTORY_H_ diff --git a/media/cdm/android_cdm_factory.cc b/media/cdm/android_cdm_factory.cc deleted file mode 100644 index bf09814..0000000 --- a/media/cdm/android_cdm_factory.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2015 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 "media/cdm/android_cdm_factory.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/location.h" -#include "base/thread_task_runner_handle.h" -#include "media/base/android/media_drm_bridge.h" -#include "media/base/key_systems.h" -#include "url/gurl.h" - -namespace media { - -AndroidCdmFactory::AndroidCdmFactory() {} - -AndroidCdmFactory::~AndroidCdmFactory() {} - -void AndroidCdmFactory::Create( - const std::string& key_system, - const GURL& security_origin, - const CdmConfig& cdm_config, - const SessionMessageCB& session_message_cb, - const SessionClosedCB& session_closed_cb, - const LegacySessionErrorCB& legacy_session_error_cb, - const SessionKeysChangeCB& session_keys_change_cb, - const SessionExpirationUpdateCB& session_expiration_update_cb, - const CdmCreatedCB& cdm_created_cb) { - if (!security_origin.is_valid()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(cdm_created_cb, nullptr, "Invalid origin.")); - return; - } - - if (!MediaDrmBridge::IsKeySystemSupported(key_system)) { - NOTREACHED() << "Key system not supported unexpectedly: " << key_system; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(cdm_created_cb, nullptr, - "Key system not supported unexpectedly.")); - return; - } - - // TODO(xhwang): Currently MediaDrmBridge can only be created on the Browser - // UI thread. Create it here after that is fixed. See http://crbug.com/546108 - NOTIMPLEMENTED(); - - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(cdm_created_cb, nullptr, "MediaDrmBridge cannot be created.")); -} - -} // namespace media diff --git a/media/media.gyp b/media/media.gyp index 2ca6e55..9bd687b 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -717,12 +717,6 @@ 'capture/webm_muxer.h', ], }], - ['enable_browser_cdms==1', { - 'sources': [ - 'base/browser_cdm_factory.cc', - 'base/browser_cdm_factory.h', - ], - }], ['OS=="android"', { 'dependencies': [ 'media_android_jni_headers', @@ -1842,10 +1836,10 @@ 'sources': [ 'base/android/access_unit_queue.cc', 'base/android/access_unit_queue.h', + 'base/android/android_cdm_factory.cc', + 'base/android/android_cdm_factory.h', 'base/android/audio_decoder_job.cc', 'base/android/audio_decoder_job.h', - 'base/android/browser_cdm_factory_android.cc', - 'base/android/browser_cdm_factory_android.h', 'base/android/demuxer_android.h', 'base/android/demuxer_stream_player_params.cc', 'base/android/demuxer_stream_player_params.h', diff --git a/media/mojo/services/android_mojo_media_client.cc b/media/mojo/services/android_mojo_media_client.cc index e295a73..a5ee93a 100644 --- a/media/mojo/services/android_mojo_media_client.cc +++ b/media/mojo/services/android_mojo_media_client.cc @@ -5,8 +5,8 @@ #include "media/mojo/services/mojo_media_client.h" #include "base/memory/scoped_ptr.h" +#include "media/base/android/android_cdm_factory.h" #include "media/base/media.h" -#include "media/cdm/android_cdm_factory.h" namespace media { namespace internal { @@ -28,4 +28,4 @@ scoped_ptr<PlatformMojoMediaClient> CreatePlatformMojoMediaClient() { } } // namespace internal -} // namespace media
\ No newline at end of file +} // namespace media |