blob: 47c4fdd761a7b08921d2bb1ce5c66bbd74acdbff [file] [log] [blame]
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01001// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01005#include "content/renderer/media/crypto/proxy_decryptor.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01006
7#include "base/bind.h"
8#include "base/callback_helpers.h"
9#include "base/logging.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010010#include "content/renderer/media/crypto/content_decryption_module_factory.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010011
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010012namespace content {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010013
14#if defined(ENABLE_PEPPER_CDMS)
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010015void ProxyDecryptor::DestroyHelperPlugin() {
Ben Murdocheb525c52013-07-10 11:40:50 +010016 ContentDecryptionModuleFactory::DestroyHelperPlugin(
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +010017 web_media_player_client_, web_frame_);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010018}
19#endif // defined(ENABLE_PEPPER_CDMS)
20
21ProxyDecryptor::ProxyDecryptor(
Ben Murdocheb525c52013-07-10 11:40:50 +010022#if defined(ENABLE_PEPPER_CDMS)
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010023 WebKit::WebMediaPlayerClient* web_media_player_client,
24 WebKit::WebFrame* web_frame,
Ben Murdocheb525c52013-07-10 11:40:50 +010025#elif defined(OS_ANDROID)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010026 WebMediaPlayerProxyAndroid* proxy,
27 int media_keys_id,
Ben Murdocheb525c52013-07-10 11:40:50 +010028#endif // defined(ENABLE_PEPPER_CDMS)
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010029 const media::KeyAddedCB& key_added_cb,
30 const media::KeyErrorCB& key_error_cb,
Ben Murdocheb525c52013-07-10 11:40:50 +010031 const media::KeyMessageCB& key_message_cb)
32 : weak_ptr_factory_(this),
33#if defined(ENABLE_PEPPER_CDMS)
34 web_media_player_client_(web_media_player_client),
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010035 web_frame_(web_frame),
Ben Murdocheb525c52013-07-10 11:40:50 +010036#elif defined(OS_ANDROID)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010037 proxy_(proxy),
38 media_keys_id_(media_keys_id),
Ben Murdocheb525c52013-07-10 11:40:50 +010039#endif // defined(ENABLE_PEPPER_CDMS)
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010040 key_added_cb_(key_added_cb),
41 key_error_cb_(key_error_cb),
Ben Murdocheb525c52013-07-10 11:40:50 +010042 key_message_cb_(key_message_cb) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010043}
44
45ProxyDecryptor::~ProxyDecryptor() {
46 // Destroy the decryptor explicitly before destroying the plugin.
47 {
48 base::AutoLock auto_lock(lock_);
Ben Murdocheb525c52013-07-10 11:40:50 +010049 media_keys_.reset();
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010050 }
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010051}
52
53// TODO(xhwang): Support multiple decryptor notification request (e.g. from
54// video and audio decoders). The current implementation is okay for the current
55// media pipeline since we initialize audio and video decoders in sequence.
56// But ProxyDecryptor should not depend on media pipeline's implementation
57// detail.
58void ProxyDecryptor::SetDecryptorReadyCB(
59 const media::DecryptorReadyCB& decryptor_ready_cb) {
60 base::AutoLock auto_lock(lock_);
61
62 // Cancels the previous decryptor request.
63 if (decryptor_ready_cb.is_null()) {
64 if (!decryptor_ready_cb_.is_null())
65 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL);
66 return;
67 }
68
69 // Normal decryptor request.
70 DCHECK(decryptor_ready_cb_.is_null());
Ben Murdocheb525c52013-07-10 11:40:50 +010071 if (media_keys_) {
72 decryptor_ready_cb.Run(media_keys_->GetDecryptor());
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010073 return;
74 }
75 decryptor_ready_cb_ = decryptor_ready_cb;
76}
77
Torne (Richard Coles)68043e12013-09-26 13:24:57 +010078bool ProxyDecryptor::InitializeCDM(const std::string& key_system,
79 const GURL& frame_url) {
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010080 DVLOG(1) << "InitializeCDM: key_system = " << key_system;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010081
82 base::AutoLock auto_lock(lock_);
83
Ben Murdocheb525c52013-07-10 11:40:50 +010084 DCHECK(!media_keys_);
Torne (Richard Coles)68043e12013-09-26 13:24:57 +010085 media_keys_ = CreateMediaKeys(key_system, frame_url);
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +010086 if (!media_keys_)
87 return false;
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010088
Torne (Richard Coles)4e180b62013-10-18 15:46:22 +010089 if (!decryptor_ready_cb_.is_null())
90 base::ResetAndReturn(&decryptor_ready_cb_).Run(media_keys_->GetDecryptor());
91 return true;
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010092}
93
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010094bool ProxyDecryptor::GenerateKeyRequest(const std::string& type,
95 const uint8* init_data,
96 int init_data_length) {
Ben Murdocheb525c52013-07-10 11:40:50 +010097 if (!media_keys_->GenerateKeyRequest(type, init_data, init_data_length)) {
98 media_keys_.reset();
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010099 return false;
100 }
101
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100102 return true;
103}
104
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100105void ProxyDecryptor::AddKey(const uint8* key,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100106 int key_length,
107 const uint8* init_data,
108 int init_data_length,
109 const std::string& session_id) {
110 DVLOG(1) << "AddKey()";
111
112 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called.
Ben Murdocheb525c52013-07-10 11:40:50 +0100113 media_keys_->AddKey(key, key_length, init_data, init_data_length, session_id);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100114}
115
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100116void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100117 DVLOG(1) << "CancelKeyRequest()";
118
119 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called.
Ben Murdocheb525c52013-07-10 11:40:50 +0100120 media_keys_->CancelKeyRequest(session_id);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100121}
122
Ben Murdocheb525c52013-07-10 11:40:50 +0100123scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys(
Torne (Richard Coles)68043e12013-09-26 13:24:57 +0100124 const std::string& key_system,
125 const GURL& frame_url) {
Ben Murdocheb525c52013-07-10 11:40:50 +0100126 return ContentDecryptionModuleFactory::Create(
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100127 key_system,
Ben Murdocheb525c52013-07-10 11:40:50 +0100128#if defined(ENABLE_PEPPER_CDMS)
129 web_media_player_client_,
130 web_frame_,
131 base::Bind(&ProxyDecryptor::DestroyHelperPlugin,
132 weak_ptr_factory_.GetWeakPtr()),
133#elif defined(OS_ANDROID)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100134 proxy_,
135 media_keys_id_,
Torne (Richard Coles)68043e12013-09-26 13:24:57 +0100136 frame_url,
Ben Murdocheb525c52013-07-10 11:40:50 +0100137#endif // defined(ENABLE_PEPPER_CDMS)
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100138 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()),
139 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()),
Ben Murdocheb525c52013-07-10 11:40:50 +0100140 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()));
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100141}
142
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100143void ProxyDecryptor::KeyAdded(const std::string& session_id) {
144 key_added_cb_.Run(session_id);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100145}
146
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100147void ProxyDecryptor::KeyError(const std::string& session_id,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100148 media::MediaKeys::KeyError error_code,
149 int system_code) {
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100150 key_error_cb_.Run(session_id, error_code, system_code);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100151}
152
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100153void ProxyDecryptor::KeyMessage(const std::string& session_id,
Ben Murdocheb525c52013-07-10 11:40:50 +0100154 const std::vector<uint8>& message,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100155 const std::string& default_url) {
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100156 key_message_cb_.Run(session_id, message, default_url);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100157}
158
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100159} // namespace content