Chromium Code Reviews| Index: media/base/android/media_drm_proxy.cc |
| diff --git a/media/base/android/media_drm_proxy.cc b/media/base/android/media_drm_proxy.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..00d05a42b37e13558cfd6478425da0f8547afe7e |
| --- /dev/null |
| +++ b/media/base/android/media_drm_proxy.cc |
| @@ -0,0 +1,199 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
|
qinmin
2015/09/15 21:10:44
s/2013/2015/
Tima Vaisburd
2015/09/15 23:48:56
Done.
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "media/base/android/media_drm_proxy.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/thread_task_runner_handle.h" |
| + |
|
qinmin
2015/09/15 21:10:44
no blank line here
Tima Vaisburd
2015/09/15 23:48:56
Done.
|
| +#include "media/base/android/media_codec_player.h" // for GetMediaTaskRunner() |
| +#include "media/base/android/media_drm_bridge.h" |
| +#include "media/base/cdm_key_information.h" |
| + |
|
qinmin
2015/09/15 21:10:45
ditto
Tima Vaisburd
2015/09/15 23:48:56
Done.
|
| +#include "third_party/widevine/cdm/widevine_cdm_common.h" |
| + |
| +#define RUN_ON_MEDIA_THREAD(METHOD, ...) \ |
|
qinmin
2015/09/15 21:10:44
s/METHOD/method/
qinmin
2015/09/15 21:10:45
I would rename this to RUN_ON_MEDIA_THREAD_AND_RET
Tima Vaisburd
2015/09/15 23:48:56
I understood the meaning to be "make this method e
Tima Vaisburd
2015/09/15 23:48:56
Done.
|
| + do { \ |
| + if (!GetMediaTaskRunner()->BelongsToCurrentThread()) { \ |
| + /*DCHECK(ui_task_runner_->BelongsToCurrentThread());*/ \ |
|
qinmin
2015/09/15 21:10:45
remove this, it is implied by the above if stateme
Tima Vaisburd
2015/09/15 23:48:56
Done.
|
| + GetMediaTaskRunner()->PostTask( \ |
| + FROM_HERE, base::Bind(&MediaDrmProxy::METHOD, media_weak_this_, \ |
| + ##__VA_ARGS__)); \ |
| + return; \ |
| + } \ |
| + } while (0) |
| + |
| +namespace media { |
| + |
| +// static |
| +scoped_ptr<MediaDrmProxy, BrowserCdmDeleter> MediaDrmProxy::Create( |
| + const std::string& key_system, |
| + MediaDrmBridge::SecurityLevel widevine_security_level, |
| + 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) { |
| + scoped_ptr<MediaDrmProxy, BrowserCdmDeleter> media_drm_proxy; |
| + |
| + // Perform as many checks as we can on the UI thread before we do |
| + // the creation asynchronously on Media thread. |
| + if (!MediaDrmBridge::CanCreate(key_system, widevine_security_level)) |
| + return media_drm_proxy.Pass(); |
| + |
| + media_drm_proxy.reset( |
| + new MediaDrmProxy(key_system, widevine_security_level, session_message_cb, |
| + session_closed_cb, legacy_session_error_cb, |
| + session_keys_change_cb, session_expiration_update_cb)); |
| + |
| + // The actual work is done on the Media thread and there the creation |
| + // might fail, but we are still passing a valid pointer. |
| + return media_drm_proxy.Pass(); |
| +} |
| + |
| +MediaDrmProxy::MediaDrmProxy( |
| + const std::string& key_system, |
| + MediaDrmBridge::SecurityLevel widevine_security_level, |
| + 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) |
| + : ui_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| + key_system_(key_system), |
| + widevine_security_level_(widevine_security_level), |
| + session_message_cb_(session_message_cb), |
| + session_closed_cb_(session_closed_cb), |
| + legacy_session_error_cb_(legacy_session_error_cb), |
| + session_keys_change_cb_(session_keys_change_cb), |
| + session_expiration_update_cb_(session_expiration_update_cb), |
| + media_weak_factory_(this) { |
| + media_weak_this_ = media_weak_factory_.GetWeakPtr(); |
| + |
| + // Perform MediaDrmBridge creation on the Media thread. |
| + GetMediaTaskRunner()->PostTask( |
| + FROM_HERE, base::Bind(&MediaDrmProxy::Initialize, media_weak_this_)); |
| +} |
| + |
| +MediaDrmProxy::~MediaDrmProxy() { |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| +} |
| + |
| +void MediaDrmProxy::DeleteOnCorrectThread() { |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + |
| + // Post deletion onto Media thread |
| + GetMediaTaskRunner()->DeleteSoon(FROM_HERE, this); |
| +} |
| + |
| +void MediaDrmProxy::Initialize() { |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + |
| + // Pass the original callbacks, those that should be called on UI thread. |
| + media_drm_bridge_ = |
| + scoped_ptr<MediaDrmBridge, BrowserCdmDeleter>(MediaDrmBridge::Create( |
| + key_system_, |
| + widevine_security_level_, |
| + session_message_cb_, |
| + session_closed_cb_, |
| + legacy_session_error_cb_, |
| + session_keys_change_cb_, |
| + session_expiration_update_cb_)); |
| + |
| + if (!media_drm_bridge_) |
| + DVLOG(1) << __FUNCTION__ << ": MediaDrmBridge::Create() failed"; |
| +} |
| + |
| +void MediaDrmProxy::SetServerCertificate( |
| + const std::vector<uint8_t>& certificate, |
| + scoped_ptr<media::SimpleCdmPromise> promise) { |
| + RUN_ON_MEDIA_THREAD(SetServerCertificate, certificate, |
| + base::Passed(&promise)); |
| + |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + |
| + media_drm_bridge_->SetServerCertificate(certificate, promise.Pass()); |
| +} |
| + |
| +void MediaDrmProxy::CreateSessionAndGenerateRequest( |
| + SessionType session_type, |
| + media::EmeInitDataType init_data_type, |
| + const std::vector<uint8_t>& init_data, |
| + scoped_ptr<media::NewSessionCdmPromise> promise) { |
| + RUN_ON_MEDIA_THREAD(CreateSessionAndGenerateRequest, session_type, |
| + init_data_type, init_data, base::Passed(&promise)); |
| + |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + |
| + media_drm_bridge_->CreateSessionAndGenerateRequest( |
| + session_type, init_data_type, init_data, promise.Pass()); |
| +} |
| + |
| +void MediaDrmProxy::LoadSession( |
| + SessionType session_type, |
| + const std::string& session_id, |
| + scoped_ptr<media::NewSessionCdmPromise> promise) { |
| + RUN_ON_MEDIA_THREAD(LoadSession, session_type, session_id, |
| + base::Passed(&promise)); |
| + |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + |
| + media_drm_bridge_->LoadSession(session_type, session_id, promise.Pass()); |
| +} |
| + |
| +void MediaDrmProxy::UpdateSession(const std::string& session_id, |
| + const std::vector<uint8_t>& response, |
| + scoped_ptr<media::SimpleCdmPromise> promise) { |
| + RUN_ON_MEDIA_THREAD(UpdateSession, session_id, response, |
| + base::Passed(&promise)); |
| + |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + |
| + media_drm_bridge_->UpdateSession(session_id, response, promise.Pass()); |
| +} |
| + |
| +void MediaDrmProxy::CloseSession(const std::string& session_id, |
| + scoped_ptr<media::SimpleCdmPromise> promise) { |
| + RUN_ON_MEDIA_THREAD(CloseSession, session_id, base::Passed(&promise)); |
| + |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + |
| + media_drm_bridge_->CloseSession(session_id, promise.Pass()); |
| +} |
| + |
| +void MediaDrmProxy::RemoveSession(const std::string& session_id, |
| + scoped_ptr<media::SimpleCdmPromise> promise) { |
| + RUN_ON_MEDIA_THREAD(RemoveSession, session_id, base::Passed(&promise)); |
| + |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + |
| + media_drm_bridge_->RemoveSession(session_id, promise.Pass()); |
| +} |
| + |
| +CdmContext* MediaDrmProxy::GetCdmContext() { |
| + NOTREACHED(); |
| + return nullptr; |
| +} |
| + |
| +int MediaDrmProxy::RegisterPlayer(const base::Closure& new_key_cb, |
| + const base::Closure& cdm_unset_cb) { |
| + // Synchronous? |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + return media_drm_bridge_->RegisterPlayer(new_key_cb, cdm_unset_cb); |
| +} |
| + |
| +void MediaDrmProxy::UnregisterPlayer(int registration_id) { |
| + // Synchronous? |
| + DVLOG(1) << "MediaDrmProxy::" << __FUNCTION__; |
| + media_drm_bridge_->UnregisterPlayer(registration_id); |
| +} |
| + |
| +MediaDrmBridge* MediaDrmProxy::GetDrmBridge() { |
| + DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| + |
| + return media_drm_bridge_.get(); |
| +} |
| + |
| +} // namespace media |