1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/renderer/media/crypto/proxy_decryptor.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/renderer/media/crypto/content_decryption_module_factory.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace content { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(ENABLE_PEPPER_CDMS) 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ProxyDecryptor::DestroyHelperPlugin() { 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ContentDecryptionModuleFactory::DestroyHelperPlugin( 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_media_player_client_); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif // defined(ENABLE_PEPPER_CDMS) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyDecryptor::ProxyDecryptor( 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(ENABLE_PEPPER_CDMS) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebMediaPlayerClient* web_media_player_client, 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebKit::WebFrame* web_frame, 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#elif defined(OS_ANDROID) 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch WebMediaPlayerProxyAndroid* proxy, 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int media_keys_id, 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif // defined(ENABLE_PEPPER_CDMS) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const media::KeyAddedCB& key_added_cb, 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const media::KeyErrorCB& key_error_cb, 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const media::KeyMessageCB& key_message_cb) 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : weak_ptr_factory_(this), 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(ENABLE_PEPPER_CDMS) 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_media_player_client_(web_media_player_client), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_frame_(web_frame), 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#elif defined(OS_ANDROID) 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch proxy_(proxy), 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch media_keys_id_(media_keys_id), 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif // defined(ENABLE_PEPPER_CDMS) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_added_cb_(key_added_cb), 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key_error_cb_(key_error_cb), 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch key_message_cb_(key_message_cb) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyDecryptor::~ProxyDecryptor() { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Destroy the decryptor explicitly before destroying the plugin. 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoLock auto_lock(lock_); 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch media_keys_.reset(); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(xhwang): Support multiple decryptor notification request (e.g. from 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// video and audio decoders). The current implementation is okay for the current 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// media pipeline since we initialize audio and video decoders in sequence. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// But ProxyDecryptor should not depend on media pipeline's implementation 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// detail. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProxyDecryptor::SetDecryptorReadyCB( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const media::DecryptorReadyCB& decryptor_ready_cb) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancels the previous decryptor request. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (decryptor_ready_cb.is_null()) { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!decryptor_ready_cb_.is_null()) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Normal decryptor request. 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(decryptor_ready_cb_.is_null()); 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (media_keys_) { 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch decryptor_ready_cb.Run(media_keys_->GetDecryptor()); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decryptor_ready_cb_ = decryptor_ready_cb; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool ProxyDecryptor::InitializeCDM(const std::string& key_system) { 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DVLOG(1) << "InitializeCDM: key_system = " << key_system; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!media_keys_); 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch media_keys_ = CreateMediaKeys(key_system); 857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return media_keys_ != NULL; 877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool ProxyDecryptor::GenerateKeyRequest(const std::string& type, 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const uint8* init_data, 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int init_data_length) { 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!media_keys_->GenerateKeyRequest(type, init_data, init_data_length)) { 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch media_keys_.reset(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!decryptor_ready_cb_.is_null()) 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ResetAndReturn(&decryptor_ready_cb_).Run(media_keys_->GetDecryptor()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ProxyDecryptor::AddKey(const uint8* key, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int key_length, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* init_data, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int init_data_length, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& session_id) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "AddKey()"; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch media_keys_->AddKey(key, key_length, init_data, init_data_length, session_id); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "CancelKeyRequest()"; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch media_keys_->CancelKeyRequest(session_id); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys( 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key_system) { 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return ContentDecryptionModuleFactory::Create( 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) key_system, 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(ENABLE_PEPPER_CDMS) 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_media_player_client_, 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_frame_, 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&ProxyDecryptor::DestroyHelperPlugin, 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch weak_ptr_factory_.GetWeakPtr()), 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#elif defined(OS_ANDROID) 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch proxy_, 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch media_keys_id_, 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif // defined(ENABLE_PEPPER_CDMS) 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr())); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ProxyDecryptor::KeyAdded(const std::string& session_id) { 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) key_added_cb_.Run(session_id); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ProxyDecryptor::KeyError(const std::string& session_id, 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) media::MediaKeys::KeyError error_code, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int system_code) { 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) key_error_cb_.Run(session_id, error_code, system_code); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void ProxyDecryptor::KeyMessage(const std::string& session_id, 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::vector<uint8>& message, 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& default_url) { 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) key_message_cb_.Run(session_id, message, default_url); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace content 156