1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/media/crypto/proxy_media_keys.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <vector> 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/basictypes.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h" 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/stl_util.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/renderer/media/crypto/key_systems.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/media/crypto/renderer_cdm_manager.h" 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "media/base/cdm_promise.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content { 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create( 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& key_system, 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const GURL& security_origin, 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RendererCdmManager* manager, 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const media::SessionMessageCB& session_message_cb, 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const media::SessionReadyCB& session_ready_cb, 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const media::SessionClosedCB& session_closed_cb, 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const media::SessionErrorCB& session_error_cb, 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const media::SessionKeysChangeCB& session_keys_change_cb, 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const media::SessionExpirationUpdateCB& session_expiration_update_cb) { 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(manager); 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(jrummell): Add support for SessionKeysChangeCB and 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // SessionExpirationUpdateCB. 32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_ptr<ProxyMediaKeys> proxy_media_keys( 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new ProxyMediaKeys(manager, 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch session_message_cb, 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch session_ready_cb, 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch session_closed_cb, 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch session_error_cb)); 38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch proxy_media_keys->InitializeCdm(key_system, security_origin); 39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return proxy_media_keys.Pass(); 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ProxyMediaKeys::~ProxyMediaKeys() { 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manager_->DestroyCdm(cdm_id_); 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) manager_->UnregisterMediaKeys(cdm_id_); 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Reject any outstanding promises. 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (PromiseMap::iterator it = session_id_to_promise_map_.begin(); 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it != session_id_to_promise_map_.end(); 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ++it) { 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it->second->reject( 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) media::MediaKeys::NOT_SUPPORTED_ERROR, 0, "The operation was aborted."); 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_id_to_promise_map_.clear(); 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ProxyMediaKeys::SetServerCertificate( 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const uint8* certificate_data, 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int certificate_data_length, 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<media::SimpleCdmPromise> promise) { 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented."); 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ProxyMediaKeys::CreateSession( 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& init_data_type, 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const uint8* init_data, 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int init_data_length, 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SessionType session_type, 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<media::NewSessionCdmPromise> promise) { 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(xhwang): Move these checks up to blink and DCHECK here. 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // See http://crbug.com/342510 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CdmHostMsg_CreateSession_ContentType create_session_content_type; 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (init_data_type == "cenc") { 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) create_session_content_type = CREATE_SESSION_TYPE_MP4; 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else if (init_data_type == "webm") { 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) create_session_content_type = CREATE_SESSION_TYPE_WEBM; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DLOG(ERROR) << "Unsupported EME CreateSession content type of " 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << init_data_type; 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) promise->reject( 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NOT_SUPPORTED_ERROR, 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0, 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "Unsupported EME CreateSession init data type of " + init_data_type); 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uint32 session_id = CreateSessionId(); 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SavePromise(session_id, promise.PassAs<media::CdmPromise>()); 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) manager_->CreateSession( 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) cdm_id_, 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_id, 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) create_session_content_type, 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<uint8>(init_data, init_data + init_data_length)); 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ProxyMediaKeys::LoadSession( 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& web_session_id, 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<media::NewSessionCdmPromise> promise) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(xhwang): Check key system and platform support for LoadSession in 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // blink and add NOTREACHED() here. 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DLOG(ERROR) << "ProxyMediaKeys doesn't support session loading."; 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ProxyMediaKeys::UpdateSession( 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& web_session_id, 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const uint8* response, 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int response_length, 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<media::SimpleCdmPromise> promise) { 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uint32 session_id = LookupSessionId(web_session_id); 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!session_id) { 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SavePromise(session_id, promise.PassAs<media::CdmPromise>()); 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) manager_->UpdateSession( 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) cdm_id_, 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_id, 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<uint8>(response, response + response_length)); 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ProxyMediaKeys::CloseSession(const std::string& web_session_id, 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<media::SimpleCdmPromise> promise) { 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uint32 session_id = LookupSessionId(web_session_id); 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!session_id) { 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SavePromise(session_id, promise.PassAs<media::CdmPromise>()); 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manager_->ReleaseSession(cdm_id_, session_id); 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ProxyMediaKeys::RemoveSession( 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& web_session_id, 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<media::SimpleCdmPromise> promise) { 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented."); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ProxyMediaKeys::GetUsableKeyIds(const std::string& web_session_id, 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<media::KeyIdsPromise> promise) { 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented."); 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProxyMediaKeys::OnSessionCreated(uint32 session_id, 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& web_session_id) { 147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AssignWebSessionId(session_id, web_session_id); 148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<media::CdmPromise> promise = TakePromise(session_id); 149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (promise) { 150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) media::NewSessionCdmPromise* session_promise( 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static_cast<media::NewSessionCdmPromise*>(promise.get())); 152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_promise->resolve(web_session_id); 153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProxyMediaKeys::OnSessionMessage(uint32 session_id, 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::vector<uint8>& message, 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& destination_url) { 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_message_cb_.Run( 160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LookupWebSessionId(session_id), message, destination_url); 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProxyMediaKeys::OnSessionReady(uint32 session_id) { 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<media::CdmPromise> promise = TakePromise(session_id); 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (promise) { 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) media::SimpleCdmPromise* simple_promise( 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static_cast<media::SimpleCdmPromise*>(promise.get())); 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) simple_promise->resolve(); 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Still needed for keyadded. 171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string web_session_id = LookupWebSessionId(session_id); 172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_ready_cb_.Run(web_session_id); 173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProxyMediaKeys::OnSessionClosed(uint32 session_id) { 177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string web_session_id = LookupWebSessionId(session_id); 178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DropWebSessionId(web_session_id); 179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<media::CdmPromise> promise = TakePromise(session_id); 180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (promise) { 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) media::SimpleCdmPromise* simple_promise( 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static_cast<media::SimpleCdmPromise*>(promise.get())); 183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) simple_promise->resolve(); 184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // It is possible for the CDM to close a session independent of a 186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Release() request. 187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_closed_cb_.Run(web_session_id); 188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProxyMediaKeys::OnSessionError(uint32 session_id, 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) media::MediaKeys::KeyError error_code, 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32 system_code) { 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string web_session_id = LookupWebSessionId(session_id); 195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) media::MediaKeys::Exception exception_code; 196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switch (error_code) { 197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case media::MediaKeys::kClientError: 198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) exception_code = media::MediaKeys::CLIENT_ERROR; 199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case media::MediaKeys::kOutputError: 201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) exception_code = media::MediaKeys::OUTPUT_ERROR; 202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case media::MediaKeys::kUnknownError: 204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) default: 205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) exception_code = media::MediaKeys::UNKNOWN_ERROR; 206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<media::CdmPromise> promise = TakePromise(session_id); 210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (promise) { 211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) promise->reject(exception_code, system_code, std::string()); 212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Errors generally happen in response to a request, but it is possible 216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // for something bad to happen in the CDM and it needs to tell the client. 217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_error_cb_.Run( 218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) web_session_id, exception_code, system_code, std::string()); 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 221e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochint ProxyMediaKeys::GetCdmId() const { 222e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return cdm_id_; 223e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 224e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochProxyMediaKeys::ProxyMediaKeys( 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RendererCdmManager* manager, 227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const media::SessionMessageCB& session_message_cb, 228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const media::SessionReadyCB& session_ready_cb, 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const media::SessionClosedCB& session_closed_cb, 230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const media::SessionErrorCB& session_error_cb) 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : manager_(manager), 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch session_message_cb_(session_message_cb), 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch session_ready_cb_(session_ready_cb), 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch session_closed_cb_(session_closed_cb), 235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_error_cb_(session_error_cb), 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) next_session_id_(1) { 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cdm_id_ = manager->RegisterMediaKeys(this); 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ProxyMediaKeys::InitializeCdm(const std::string& key_system, 241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const GURL& security_origin) { 242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch manager_->InitializeCdm(cdm_id_, this, key_system, security_origin); 243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)uint32_t ProxyMediaKeys::CreateSessionId() { 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return next_session_id_++; 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ProxyMediaKeys::AssignWebSessionId(uint32_t session_id, 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& web_session_id) { 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!ContainsKey(web_session_to_session_id_map_, web_session_id)); 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(session_id); 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) web_session_to_session_id_map_.insert( 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::make_pair(web_session_id, session_id)); 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)uint32_t ProxyMediaKeys::LookupSessionId( 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& web_session_id) const { 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SessionIdMap::const_iterator it = 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) web_session_to_session_id_map_.find(web_session_id); 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return (it != web_session_to_session_id_map_.end()) ? it->second : 0; 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)std::string ProxyMediaKeys::LookupWebSessionId(uint32_t session_id) const { 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (SessionIdMap::const_iterator it = web_session_to_session_id_map_.begin(); 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) it != web_session_to_session_id_map_.end(); 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ++it) { 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (it->second == session_id) 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return it->first; 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Possible to get an error creating a session, so no |web_session_id| 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // available. 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return std::string(); 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ProxyMediaKeys::DropWebSessionId(const std::string& web_session_id) { 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) web_session_to_session_id_map_.erase(web_session_id); 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ProxyMediaKeys::SavePromise(uint32_t session_id, 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<media::CdmPromise> promise) { 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Should only be one promise outstanding for any |session_id|. 283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!ContainsKey(session_id_to_promise_map_, session_id)); 284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) session_id_to_promise_map_.add(session_id, promise.Pass()); 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_ptr<media::CdmPromise> ProxyMediaKeys::TakePromise(uint32_t session_id) { 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) PromiseMap::iterator it = session_id_to_promise_map_.find(session_id); 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // May not be a promise associated with this session for asynchronous events. 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (it == session_id_to_promise_map_.end()) 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return scoped_ptr<media::CdmPromise>(); 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return session_id_to_promise_map_.take_and_erase(it); 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace content 296