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 #ifndef CONTENT_RENDERER_MEDIA_CDM_SESSION_ADAPTER_H_ 6 #define CONTENT_RENDERER_MEDIA_CDM_SESSION_ADAPTER_H_ 7 8 #include <map> 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/containers/hash_tables.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/weak_ptr.h" 15 #include "media/base/media_keys.h" 16 #include "third_party/WebKit/public/platform/WebContentDecryptionModuleSession.h" 17 18 #if defined(ENABLE_PEPPER_CDMS) 19 #include "content/renderer/media/crypto/pepper_cdm_wrapper.h" 20 #endif 21 22 class GURL; 23 24 namespace content { 25 26 #if defined(ENABLE_BROWSER_CDMS) 27 class RendererCdmManager; 28 #endif 29 30 class WebContentDecryptionModuleSessionImpl; 31 32 // Owns the CDM instance and makes calls from session objects to the CDM. 33 // Forwards the web session ID-based callbacks of the MediaKeys interface to the 34 // appropriate session object. Callers should hold references to this class 35 // as long as they need the CDM instance. 36 class CdmSessionAdapter : public base::RefCounted<CdmSessionAdapter> { 37 public: 38 CdmSessionAdapter(); 39 40 // Returns true on success. 41 bool Initialize( 42 #if defined(ENABLE_PEPPER_CDMS) 43 const CreatePepperCdmCB& create_pepper_cdm_cb, 44 #elif defined(ENABLE_BROWSER_CDMS) 45 RendererCdmManager* manager, 46 #endif 47 const std::string& key_system, 48 const GURL& security_origin); 49 50 // Provides a server certificate to be used to encrypt messages to the 51 // license server. 52 void SetServerCertificate(const uint8* server_certificate, 53 int server_certificate_length, 54 scoped_ptr<media::SimpleCdmPromise> promise); 55 56 // Creates a new session and adds it to the internal map. The caller owns the 57 // created session. RemoveSession() must be called when destroying it, if 58 // RegisterSession() was called. 59 WebContentDecryptionModuleSessionImpl* CreateSession(); 60 61 // Adds a session to the internal map. Called once the session is successfully 62 // initialized. Returns true if the session was registered, false if there is 63 // already an existing session with the same |web_session_id|. 64 bool RegisterSession( 65 const std::string& web_session_id, 66 base::WeakPtr<WebContentDecryptionModuleSessionImpl> session); 67 68 // Removes a session from the internal map. 69 void UnregisterSession(const std::string& web_session_id); 70 71 // Initializes a session with the |init_data_type|, |init_data| and 72 // |session_type| provided. 73 void InitializeNewSession(const std::string& init_data_type, 74 const uint8* init_data, 75 int init_data_length, 76 media::MediaKeys::SessionType session_type, 77 scoped_ptr<media::NewSessionCdmPromise> promise); 78 79 // Updates the session specified by |web_session_id| with |response|. 80 void UpdateSession(const std::string& web_session_id, 81 const uint8* response, 82 int response_length, 83 scoped_ptr<media::SimpleCdmPromise> promise); 84 85 // Closes the session specified by |web_session_id|. 86 void CloseSession(const std::string& web_session_id, 87 scoped_ptr<media::SimpleCdmPromise> promise); 88 89 // Removes stored session data associated with the session specified by 90 // |web_session_id|. 91 void RemoveSession(const std::string& web_session_id, 92 scoped_ptr<media::SimpleCdmPromise> promise); 93 94 // Retrieves the key IDs for keys in the session that the CDM knows are 95 // currently usable to decrypt media data. 96 void GetUsableKeyIds(const std::string& web_session_id, 97 scoped_ptr<media::KeyIdsPromise> promise); 98 99 // Returns the Decryptor associated with this CDM. May be NULL if no 100 // Decryptor is associated with the MediaKeys object. 101 // TODO(jrummell): Figure out lifetimes, as WMPI may still use the decryptor 102 // after WebContentDecryptionModule is freed. http://crbug.com/330324 103 media::Decryptor* GetDecryptor(); 104 105 // Returns a prefix to use for UMAs. 106 const std::string& GetKeySystemUMAPrefix() const; 107 108 #if defined(ENABLE_BROWSER_CDMS) 109 // Returns the CDM ID associated with the |media_keys_|. May be kInvalidCdmId 110 // if no CDM ID is associated. 111 int GetCdmId() const; 112 #endif 113 114 private: 115 friend class base::RefCounted<CdmSessionAdapter>; 116 typedef base::hash_map<std::string, 117 base::WeakPtr<WebContentDecryptionModuleSessionImpl> > 118 SessionMap; 119 120 ~CdmSessionAdapter(); 121 122 // Callbacks for firing session events. 123 void OnSessionMessage(const std::string& web_session_id, 124 const std::vector<uint8>& message, 125 const GURL& destination_url); 126 void OnSessionKeysChange(const std::string& web_session_id, 127 bool has_additional_usable_key); 128 void OnSessionExpirationUpdate(const std::string& web_session_id, 129 const base::Time& new_expiry_time); 130 void OnSessionReady(const std::string& web_session_id); 131 void OnSessionClosed(const std::string& web_session_id); 132 void OnSessionError(const std::string& web_session_id, 133 media::MediaKeys::Exception exception_code, 134 uint32 system_code, 135 const std::string& error_message); 136 137 // Helper function of the callbacks. 138 WebContentDecryptionModuleSessionImpl* GetSession( 139 const std::string& web_session_id); 140 141 scoped_ptr<media::MediaKeys> media_keys_; 142 143 SessionMap sessions_; 144 145 #if defined(ENABLE_BROWSER_CDMS) 146 int cdm_id_; 147 #endif 148 149 std::string key_system_uma_prefix_; 150 151 // NOTE: Weak pointers must be invalidated before all other member variables. 152 base::WeakPtrFactory<CdmSessionAdapter> weak_ptr_factory_; 153 154 DISALLOW_COPY_AND_ASSIGN(CdmSessionAdapter); 155 }; 156 157 } // namespace content 158 159 #endif // CONTENT_RENDERER_MEDIA_CDM_SESSION_ADAPTER_H_ 160