1 // Copyright 2013 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 #ifndef CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_ 6 #define CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/synchronization/lock.h" 16 #include "media/base/decryptor.h" 17 #include "media/base/media_keys.h" 18 19 class GURL; 20 21 namespace blink { 22 #if defined(ENABLE_PEPPER_CDMS) 23 class WebFrame; 24 class WebMediaPlayerClient; 25 #endif // defined(ENABLE_PEPPER_CDMS) 26 } 27 28 namespace content { 29 30 #if defined(OS_ANDROID) 31 class RendererMediaPlayerManager; 32 #endif // defined(OS_ANDROID) 33 34 // ProxyDecryptor is for EME v0.1b only. It should not be used for the WD API. 35 // A decryptor proxy that creates a real decryptor object on demand and 36 // forwards decryptor calls to it. 37 // 38 // Now that the Pepper API calls use session ID to match responses with 39 // requests, this class maintains a mapping between session ID and web session 40 // ID. Callers of this class expect web session IDs in the responses. 41 // Session IDs are internal unique references to the session. Web session IDs 42 // are the CDM generated ID for the session, and are what are visible to users. 43 // 44 // TODO(xhwang): Currently we don't support run-time switching among decryptor 45 // objects. Fix this when needed. 46 // TODO(xhwang): The ProxyDecryptor is not a Decryptor. Find a better name! 47 class ProxyDecryptor { 48 public: 49 // These are similar to the callbacks in media_keys.h, but pass back the 50 // web session ID rather than the internal session ID. 51 typedef base::Callback<void(const std::string& session_id)> KeyAddedCB; 52 typedef base::Callback<void(const std::string& session_id, 53 media::MediaKeys::KeyError error_code, 54 int system_code)> KeyErrorCB; 55 typedef base::Callback<void(const std::string& session_id, 56 const std::vector<uint8>& message, 57 const std::string& default_url)> KeyMessageCB; 58 59 ProxyDecryptor( 60 #if defined(ENABLE_PEPPER_CDMS) 61 blink::WebMediaPlayerClient* web_media_player_client, 62 blink::WebFrame* web_frame, 63 #elif defined(OS_ANDROID) 64 RendererMediaPlayerManager* manager, 65 int media_keys_id, 66 #endif // defined(ENABLE_PEPPER_CDMS) 67 const KeyAddedCB& key_added_cb, 68 const KeyErrorCB& key_error_cb, 69 const KeyMessageCB& key_message_cb); 70 virtual ~ProxyDecryptor(); 71 72 // Only call this once. 73 bool InitializeCDM(const std::string& key_system, const GURL& frame_url); 74 75 // Requests the ProxyDecryptor to notify the decryptor when it's ready through 76 // the |decryptor_ready_cb| provided. 77 // If |decryptor_ready_cb| is null, the existing callback will be fired with 78 // NULL immediately and reset. 79 void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb); 80 81 // May only be called after InitializeCDM() succeeds. 82 bool GenerateKeyRequest(const std::string& type, 83 const uint8* init_data, 84 int init_data_length); 85 void AddKey(const uint8* key, int key_length, 86 const uint8* init_data, int init_data_length, 87 const std::string& session_id); 88 void CancelKeyRequest(const std::string& session_id); 89 90 private: 91 // Session_id <-> web_session_id map. 92 typedef std::map<uint32, std::string> SessionIdMap; 93 94 // Helper function to create MediaKeys to handle the given |key_system|. 95 scoped_ptr<media::MediaKeys> CreateMediaKeys(const std::string& key_system, 96 const GURL& frame_url); 97 98 // Callbacks for firing session events. 99 void OnSessionCreated(uint32 session_id, const std::string& web_session_id); 100 void OnSessionMessage(uint32 session_id, 101 const std::vector<uint8>& message, 102 const std::string& default_url); 103 void OnSessionReady(uint32 session_id); 104 void OnSessionClosed(uint32 session_id); 105 void OnSessionError(uint32 session_id, 106 media::MediaKeys::KeyError error_code, 107 int system_code); 108 109 // Helper function to determine session_id for the provided |web_session_id|. 110 uint32 LookupSessionId(const std::string& web_session_id); 111 112 // Helper function to determine web_session_id for the provided |session_id|. 113 // The returned web_session_id is only valid on the main thread, and should be 114 // stored by copy. 115 const std::string& LookupWebSessionId(uint32 session_id); 116 117 base::WeakPtrFactory<ProxyDecryptor> weak_ptr_factory_; 118 119 #if defined(ENABLE_PEPPER_CDMS) 120 // Callback for cleaning up a Pepper-based CDM. 121 void DestroyHelperPlugin(); 122 123 // Needed to create the PpapiDecryptor. 124 blink::WebMediaPlayerClient* web_media_player_client_; 125 blink::WebFrame* web_frame_; 126 #elif defined(OS_ANDROID) 127 RendererMediaPlayerManager* manager_; 128 int media_keys_id_; 129 #endif // defined(ENABLE_PEPPER_CDMS) 130 131 // The real MediaKeys that manages key operations for the ProxyDecryptor. 132 // This pointer is protected by the |lock_|. 133 scoped_ptr<media::MediaKeys> media_keys_; 134 135 // Callbacks for firing key events. 136 KeyAddedCB key_added_cb_; 137 KeyErrorCB key_error_cb_; 138 KeyMessageCB key_message_cb_; 139 140 // Protects the |decryptor_|. Note that |decryptor_| itself should be thread 141 // safe as per the Decryptor interface. 142 base::Lock lock_; 143 144 media::DecryptorReadyCB decryptor_ready_cb_; 145 146 // Session IDs are used to uniquely track sessions so that CDM callbacks 147 // can get mapped to the correct session ID. Session ID should be unique 148 // per renderer process for debugging purposes. 149 static uint32 next_session_id_; 150 151 SessionIdMap sessions_; 152 153 bool is_clear_key_; 154 155 DISALLOW_COPY_AND_ASSIGN(ProxyDecryptor); 156 }; 157 158 } // namespace content 159 160 #endif // CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_ 161