Home | History | Annotate | Download | only in crypto
      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.
      4 
      5 #include "content/renderer/media/crypto/renderer_cdm_manager.h"
      6 
      7 #include "base/stl_util.h"
      8 #include "content/common/media/cdm_messages.h"
      9 #include "content/renderer/media/crypto/proxy_media_keys.h"
     10 
     11 namespace content {
     12 
     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
     18 
     19 RendererCdmManager::RendererCdmManager(RenderFrame* render_frame)
     20     : RenderFrameObserver(render_frame),
     21       next_cdm_id_(kInvalidCdmId + 1) {
     22 }
     23 
     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.";
     28 }
     29 
     30 bool RendererCdmManager::OnMessageReceived(const IPC::Message& msg) {
     31   bool handled = true;
     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)
     39   IPC_END_MESSAGE_MAP()
     40   return handled;
     41 }
     42 
     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));
     50 }
     51 
     52 void RendererCdmManager::CreateSession(
     53     int cdm_id,
     54     uint32 session_id,
     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));
     60 }
     61 
     62 void RendererCdmManager::UpdateSession(int cdm_id,
     63                                        uint32 session_id,
     64                                        const std::vector<uint8>& response) {
     65   DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
     66   Send(
     67       new CdmHostMsg_UpdateSession(routing_id(), cdm_id, session_id, response));
     68 }
     69 
     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));
     73 }
     74 
     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));
     78 }
     79 
     80 void RendererCdmManager::OnSessionCreated(int cdm_id,
     81                                           uint32 session_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);
     85     return;
     86   }
     87 
     88   ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
     89   if (media_keys)
     90     media_keys->OnSessionCreated(session_id, web_session_id);
     91 }
     92 
     93 void RendererCdmManager::OnSessionMessage(int cdm_id,
     94                                           uint32 session_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);
     99     return;
    100   }
    101 
    102   ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
    103   if (media_keys)
    104     media_keys->OnSessionMessage(session_id, message, destination_url);
    105 }
    106 
    107 void RendererCdmManager::OnSessionReady(int cdm_id, uint32 session_id) {
    108   ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
    109   if (media_keys)
    110     media_keys->OnSessionReady(session_id);
    111 }
    112 
    113 void RendererCdmManager::OnSessionClosed(int cdm_id, uint32 session_id) {
    114   ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
    115   if (media_keys)
    116     media_keys->OnSessionClosed(session_id);
    117 }
    118 
    119 void RendererCdmManager::OnSessionError(int cdm_id,
    120                                         uint32 session_id,
    121                                         media::MediaKeys::KeyError error_code,
    122                                         uint32 system_code) {
    123   ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
    124   if (media_keys)
    125     media_keys->OnSessionError(session_id, error_code, system_code);
    126 }
    127 
    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;
    133   return cdm_id;
    134 }
    135 
    136 void RendererCdmManager::UnregisterMediaKeys(int cdm_id) {
    137   DCHECK(ContainsKey(proxy_media_keys_map_, cdm_id));
    138   proxy_media_keys_map_.erase(cdm_id);
    139 }
    140 
    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;
    145 }
    146 
    147 }  // namespace content
    148