proxy_decryptor.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
1// 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 5#include "content/renderer/media/crypto/proxy_decryptor.h" 6 7#include "base/bind.h" 8#include "base/callback_helpers.h" 9#include "base/logging.h" 10#include "content/renderer/media/crypto/content_decryption_module_factory.h" 11 12namespace content { 13 14#if defined(ENABLE_PEPPER_CDMS) 15void ProxyDecryptor::DestroyHelperPlugin() { 16 ContentDecryptionModuleFactory::DestroyHelperPlugin( 17 web_media_player_client_, web_frame_); 18} 19#endif // defined(ENABLE_PEPPER_CDMS) 20 21ProxyDecryptor::ProxyDecryptor( 22#if defined(ENABLE_PEPPER_CDMS) 23 WebKit::WebMediaPlayerClient* web_media_player_client, 24 WebKit::WebFrame* web_frame, 25#elif defined(OS_ANDROID) 26 WebMediaPlayerProxyAndroid* proxy, 27 int media_keys_id, 28#endif // defined(ENABLE_PEPPER_CDMS) 29 const media::KeyAddedCB& key_added_cb, 30 const media::KeyErrorCB& key_error_cb, 31 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), 35 web_frame_(web_frame), 36#elif defined(OS_ANDROID) 37 proxy_(proxy), 38 media_keys_id_(media_keys_id), 39#endif // defined(ENABLE_PEPPER_CDMS) 40 key_added_cb_(key_added_cb), 41 key_error_cb_(key_error_cb), 42 key_message_cb_(key_message_cb) { 43} 44 45ProxyDecryptor::~ProxyDecryptor() { 46 // Destroy the decryptor explicitly before destroying the plugin. 47 { 48 base::AutoLock auto_lock(lock_); 49 media_keys_.reset(); 50 } 51} 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()); 71 if (media_keys_) { 72 decryptor_ready_cb.Run(media_keys_->GetDecryptor()); 73 return; 74 } 75 decryptor_ready_cb_ = decryptor_ready_cb; 76} 77 78bool ProxyDecryptor::InitializeCDM(const std::string& key_system, 79 const GURL& frame_url) { 80 DVLOG(1) << "InitializeCDM: key_system = " << key_system; 81 82 base::AutoLock auto_lock(lock_); 83 84 DCHECK(!media_keys_); 85 media_keys_ = CreateMediaKeys(key_system, frame_url); 86 if (!media_keys_) 87 return false; 88 89 if (!decryptor_ready_cb_.is_null()) 90 base::ResetAndReturn(&decryptor_ready_cb_).Run(media_keys_->GetDecryptor()); 91 return true; 92} 93 94bool ProxyDecryptor::GenerateKeyRequest(const std::string& type, 95 const uint8* init_data, 96 int init_data_length) { 97 if (!media_keys_->GenerateKeyRequest(type, init_data, init_data_length)) { 98 media_keys_.reset(); 99 return false; 100 } 101 102 return true; 103} 104 105void ProxyDecryptor::AddKey(const uint8* key, 106 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. 113 media_keys_->AddKey(key, key_length, init_data, init_data_length, session_id); 114} 115 116void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) { 117 DVLOG(1) << "CancelKeyRequest()"; 118 119 // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. 120 media_keys_->CancelKeyRequest(session_id); 121} 122 123scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys( 124 const std::string& key_system, 125 const GURL& frame_url) { 126 return ContentDecryptionModuleFactory::Create( 127 key_system, 128#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) 134 proxy_, 135 media_keys_id_, 136 frame_url, 137#endif // defined(ENABLE_PEPPER_CDMS) 138 base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), 139 base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), 140 base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr())); 141} 142 143void ProxyDecryptor::KeyAdded(const std::string& session_id) { 144 key_added_cb_.Run(session_id); 145} 146 147void ProxyDecryptor::KeyError(const std::string& session_id, 148 media::MediaKeys::KeyError error_code, 149 int system_code) { 150 key_error_cb_.Run(session_id, error_code, system_code); 151} 152 153void ProxyDecryptor::KeyMessage(const std::string& session_id, 154 const std::vector<uint8>& message, 155 const std::string& default_url) { 156 key_message_cb_.Run(session_id, message, default_url); 157} 158 159} // namespace content 160