1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/media/crypto/renderer_cdm_manager.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/stl_util.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/common/media/cdm_messages.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/media/crypto/proxy_media_keys.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace content { 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Maximum sizes for various EME API parameters. These are checks to prevent 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// unnecessarily large messages from being passed around, and the sizes 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// are somewhat arbitrary as the EME spec doesn't specify any limits. 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const size_t kMaxWebSessionIdLength = 512; 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const size_t kMaxSessionMessageLength = 10240; // 10 KB 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)RendererCdmManager::RendererCdmManager(RenderFrame* render_frame) 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : RenderFrameObserver(render_frame), 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) next_cdm_id_(kInvalidCdmId + 1) { 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)RendererCdmManager::~RendererCdmManager() { 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(proxy_media_keys_map_.empty()) 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << "RendererCdmManager is owned by RenderFrameImpl and is destroyed only " 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "after all ProxyMediaKeys are destroyed and unregistered."; 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool RendererCdmManager::OnMessageReceived(const IPC::Message& msg) { 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool handled = true; 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(RendererCdmManager, msg) 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_HANDLER(CdmMsg_SessionCreated, OnSessionCreated) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_HANDLER(CdmMsg_SessionMessage, OnSessionMessage) 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_HANDLER(CdmMsg_SessionReady, OnSessionReady) 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_HANDLER(CdmMsg_SessionClosed, OnSessionClosed) 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_HANDLER(CdmMsg_SessionError, OnSessionError) 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_END_MESSAGE_MAP() 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return handled; 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::InitializeCdm(int cdm_id, 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProxyMediaKeys* media_keys, 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& key_system, 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& security_origin) { 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Send(new CdmHostMsg_InitializeCdm( 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) routing_id(), cdm_id, key_system, security_origin)); 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::CreateSession( 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int cdm_id, 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 session_id, 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CdmHostMsg_CreateSession_ContentType content_type, 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<uint8>& init_data) { 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Send(new CdmHostMsg_CreateSession( 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) routing_id(), cdm_id, session_id, content_type, init_data)); 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::UpdateSession(int cdm_id, 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 session_id, 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<uint8>& response) { 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Send( 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new CdmHostMsg_UpdateSession(routing_id(), cdm_id, session_id, response)); 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::ReleaseSession(int cdm_id, uint32 session_id) { 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Send(new CdmHostMsg_ReleaseSession(routing_id(), cdm_id, session_id)); 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::DestroyCdm(int cdm_id) { 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Send(new CdmHostMsg_DestroyCdm(routing_id(), cdm_id)); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::OnSessionCreated(int cdm_id, 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 session_id, 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& web_session_id) { 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (web_session_id.length() > kMaxWebSessionIdLength) { 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (media_keys) 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_keys->OnSessionCreated(session_id, web_session_id); 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::OnSessionMessage(int cdm_id, 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 session_id, 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<uint8>& message, 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& destination_url) { 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (message.size() > kMaxSessionMessageLength) { 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (media_keys) 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_keys->OnSessionMessage(session_id, message, destination_url); 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::OnSessionReady(int cdm_id, uint32 session_id) { 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (media_keys) 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_keys->OnSessionReady(session_id); 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::OnSessionClosed(int cdm_id, uint32 session_id) { 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (media_keys) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_keys->OnSessionClosed(session_id); 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::OnSessionError(int cdm_id, 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 session_id, 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media::MediaKeys::KeyError error_code, 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 system_code) { 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (media_keys) 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_keys->OnSessionError(session_id, error_code, system_code); 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int RendererCdmManager::RegisterMediaKeys(ProxyMediaKeys* media_keys) { 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int cdm_id = next_cdm_id_++; 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_NE(cdm_id, kInvalidCdmId); 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(!ContainsKey(proxy_media_keys_map_, cdm_id)); 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) proxy_media_keys_map_[cdm_id] = media_keys; 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return cdm_id; 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RendererCdmManager::UnregisterMediaKeys(int cdm_id) { 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(ContainsKey(proxy_media_keys_map_, cdm_id)); 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) proxy_media_keys_map_.erase(cdm_id); 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ProxyMediaKeys* RendererCdmManager::GetMediaKeys(int cdm_id) { 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::map<int, ProxyMediaKeys*>::iterator iter = 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) proxy_media_keys_map_.find(cdm_id); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (iter != proxy_media_keys_map_.end()) ? iter->second : NULL; 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace content 148