1 // Copyright 2014 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.
5 #include "content/renderer/media/crypto/renderer_cdm_manager.h"
7 #include "base/stl_util.h"
8 #include "content/common/media/cdm_messages.h"
9 #include "content/renderer/media/crypto/proxy_media_keys.h"
13 // Maximum sizes for various EME API parameters. These are checks to prevent
14 // unnecessarily large messages from being passed around, and the sizes
15 // are somewhat arbitrary as the EME spec doesn't specify any limits.
16 const size_t kMaxWebSessionIdLength
= 512;
17 const size_t kMaxSessionMessageLength
= 10240; // 10 KB
19 RendererCdmManager::RendererCdmManager(RenderFrame
* render_frame
)
20 : RenderFrameObserver(render_frame
),
21 next_cdm_id_(kInvalidCdmId
+ 1) {
24 RendererCdmManager::~RendererCdmManager() {
25 DCHECK(proxy_media_keys_map_
.empty())
26 << "RendererCdmManager is owned by RenderFrameImpl and is destroyed only "
27 "after all ProxyMediaKeys are destroyed and unregistered.";
30 bool RendererCdmManager::OnMessageReceived(const IPC::Message
& msg
) {
32 IPC_BEGIN_MESSAGE_MAP(RendererCdmManager
, msg
)
33 IPC_MESSAGE_HANDLER(CdmMsg_SessionCreated
, OnSessionCreated
)
34 IPC_MESSAGE_HANDLER(CdmMsg_SessionMessage
, OnSessionMessage
)
35 IPC_MESSAGE_HANDLER(CdmMsg_SessionReady
, OnSessionReady
)
36 IPC_MESSAGE_HANDLER(CdmMsg_SessionClosed
, OnSessionClosed
)
37 IPC_MESSAGE_HANDLER(CdmMsg_SessionError
, OnSessionError
)
38 IPC_MESSAGE_UNHANDLED(handled
= false)
43 void RendererCdmManager::InitializeCdm(int cdm_id
,
44 ProxyMediaKeys
* media_keys
,
45 const std::string
& key_system
,
46 const GURL
& security_origin
) {
47 DCHECK(GetMediaKeys(cdm_id
)) << "|cdm_id| not registered.";
48 Send(new CdmHostMsg_InitializeCdm(
49 routing_id(), cdm_id
, key_system
, security_origin
));
52 void RendererCdmManager::CreateSession(
55 CdmHostMsg_CreateSession_ContentType content_type
,
56 const std::vector
<uint8
>& init_data
) {
57 DCHECK(GetMediaKeys(cdm_id
)) << "|cdm_id| not registered.";
58 Send(new CdmHostMsg_CreateSession(
59 routing_id(), cdm_id
, session_id
, content_type
, init_data
));
62 void RendererCdmManager::UpdateSession(int cdm_id
,
64 const std::vector
<uint8
>& response
) {
65 DCHECK(GetMediaKeys(cdm_id
)) << "|cdm_id| not registered.";
67 new CdmHostMsg_UpdateSession(routing_id(), cdm_id
, session_id
, response
));
70 void RendererCdmManager::ReleaseSession(int cdm_id
, uint32 session_id
) {
71 DCHECK(GetMediaKeys(cdm_id
)) << "|cdm_id| not registered.";
72 Send(new CdmHostMsg_ReleaseSession(routing_id(), cdm_id
, session_id
));
75 void RendererCdmManager::DestroyCdm(int cdm_id
) {
76 DCHECK(GetMediaKeys(cdm_id
)) << "|cdm_id| not registered.";
77 Send(new CdmHostMsg_DestroyCdm(routing_id(), cdm_id
));
80 void RendererCdmManager::OnSessionCreated(int cdm_id
,
82 const std::string
& web_session_id
) {
83 if (web_session_id
.length() > kMaxWebSessionIdLength
) {
84 OnSessionError(cdm_id
, session_id
, media::MediaKeys::kUnknownError
, 0);
88 ProxyMediaKeys
* media_keys
= GetMediaKeys(cdm_id
);
90 media_keys
->OnSessionCreated(session_id
, web_session_id
);
93 void RendererCdmManager::OnSessionMessage(int cdm_id
,
95 const std::vector
<uint8
>& message
,
96 const GURL
& destination_url
) {
97 if (message
.size() > kMaxSessionMessageLength
) {
98 OnSessionError(cdm_id
, session_id
, media::MediaKeys::kUnknownError
, 0);
102 ProxyMediaKeys
* media_keys
= GetMediaKeys(cdm_id
);
104 media_keys
->OnSessionMessage(session_id
, message
, destination_url
);
107 void RendererCdmManager::OnSessionReady(int cdm_id
, uint32 session_id
) {
108 ProxyMediaKeys
* media_keys
= GetMediaKeys(cdm_id
);
110 media_keys
->OnSessionReady(session_id
);
113 void RendererCdmManager::OnSessionClosed(int cdm_id
, uint32 session_id
) {
114 ProxyMediaKeys
* media_keys
= GetMediaKeys(cdm_id
);
116 media_keys
->OnSessionClosed(session_id
);
119 void RendererCdmManager::OnSessionError(int cdm_id
,
121 media::MediaKeys::KeyError error_code
,
122 uint32 system_code
) {
123 ProxyMediaKeys
* media_keys
= GetMediaKeys(cdm_id
);
125 media_keys
->OnSessionError(session_id
, error_code
, system_code
);
128 int RendererCdmManager::RegisterMediaKeys(ProxyMediaKeys
* media_keys
) {
129 int cdm_id
= next_cdm_id_
++;
130 DCHECK_NE(cdm_id
, kInvalidCdmId
);
131 DCHECK(!ContainsKey(proxy_media_keys_map_
, cdm_id
));
132 proxy_media_keys_map_
[cdm_id
] = media_keys
;
136 void RendererCdmManager::UnregisterMediaKeys(int cdm_id
) {
137 DCHECK(ContainsKey(proxy_media_keys_map_
, cdm_id
));
138 proxy_media_keys_map_
.erase(cdm_id
);
141 ProxyMediaKeys
* RendererCdmManager::GetMediaKeys(int cdm_id
) {
142 std::map
<int, ProxyMediaKeys
*>::iterator iter
=
143 proxy_media_keys_map_
.find(cdm_id
);
144 return (iter
!= proxy_media_keys_map_
.end()) ? iter
->second
: NULL
;
147 } // namespace content