| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/webcontentdecryptionmodule_impl.h" | 5 #include "content/renderer/media/webcontentdecryptionmodule_impl.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/bind.h" | |
| 12 #include "base/callback_helpers.h" | |
| 13 #include "base/logging.h" | 11 #include "base/logging.h" |
| 14 #include "base/memory/weak_ptr.h" | |
| 15 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 16 #include "content/renderer/media/crypto/content_decryption_module_factory.h" | 13 #include "content/renderer/media/cdm_session_adapter.h" |
| 17 #include "content/renderer/media/webcontentdecryptionmodulesession_impl.h" | 14 #include "content/renderer/media/webcontentdecryptionmodulesession_impl.h" |
| 18 #include "media/base/media_keys.h" | 15 #include "media/base/media_keys.h" |
| 19 #include "url/gurl.h" | |
| 20 | 16 |
| 21 namespace content { | 17 namespace content { |
| 22 | 18 |
| 23 // Forwards the session ID-based callbacks of the MediaKeys interface to the | 19 WebContentDecryptionModuleImpl* WebContentDecryptionModuleImpl::Create( |
| 24 // appropriate session object. | 20 const base::string16& key_system) { |
| 25 class SessionIdAdapter { | |
| 26 public: | |
| 27 SessionIdAdapter(); | |
| 28 ~SessionIdAdapter(); | |
| 29 | |
| 30 // On success, creates a MediaKeys, returns it in |media_keys|, returns true. | |
| 31 bool Initialize(const std::string& key_system, | |
| 32 scoped_ptr<media::MediaKeys>* media_keys); | |
| 33 | |
| 34 // Generates a unique internal session id. | |
| 35 uint32 GenerateSessionId(); | |
| 36 | |
| 37 // Adds a session to the internal map. Does not take ownership of the session. | |
| 38 void AddSession(uint32 session_id, | |
| 39 WebContentDecryptionModuleSessionImpl* session); | |
| 40 | |
| 41 // Removes a session from the internal map. | |
| 42 void RemoveSession(uint32 session_id); | |
| 43 | |
| 44 private: | |
| 45 typedef std::map<uint32, WebContentDecryptionModuleSessionImpl*> SessionMap; | |
| 46 | |
| 47 // Callbacks for firing session events. | |
| 48 void OnSessionCreated(uint32 session_id, const std::string& web_session_id); | |
| 49 void OnSessionMessage(uint32 session_id, | |
| 50 const std::vector<uint8>& message, | |
| 51 const std::string& destination_url); | |
| 52 void OnSessionReady(uint32 session_id); | |
| 53 void OnSessionClosed(uint32 session_id); | |
| 54 void OnSessionError(uint32 session_id, | |
| 55 media::MediaKeys::KeyError error_code, | |
| 56 int system_code); | |
| 57 | |
| 58 // Helper function of the callbacks. | |
| 59 WebContentDecryptionModuleSessionImpl* GetSession(uint32 session_id); | |
| 60 | |
| 61 base::WeakPtrFactory<SessionIdAdapter> weak_ptr_factory_; | |
| 62 | |
| 63 SessionMap sessions_; | |
| 64 | |
| 65 // Session ID should be unique per renderer process for debugging purposes. | |
| 66 static uint32 next_session_id_; | |
| 67 | |
| 68 DISALLOW_COPY_AND_ASSIGN(SessionIdAdapter); | |
| 69 }; | |
| 70 | |
| 71 const uint32 kStartingSessionId = 1; | |
| 72 uint32 SessionIdAdapter::next_session_id_ = kStartingSessionId; | |
| 73 COMPILE_ASSERT(kStartingSessionId > media::MediaKeys::kInvalidSessionId, | |
| 74 invalid_starting_value); | |
| 75 | |
| 76 SessionIdAdapter::SessionIdAdapter() | |
| 77 : weak_ptr_factory_(this) { | |
| 78 } | |
| 79 | |
| 80 SessionIdAdapter::~SessionIdAdapter() { | |
| 81 } | |
| 82 | |
| 83 bool SessionIdAdapter::Initialize(const std::string& key_system, | |
| 84 scoped_ptr<media::MediaKeys>* media_keys) { | |
| 85 DCHECK(media_keys); | |
| 86 DCHECK(!*media_keys); | |
| 87 | |
| 88 base::WeakPtr<SessionIdAdapter> weak_this = weak_ptr_factory_.GetWeakPtr(); | |
| 89 scoped_ptr<media::MediaKeys> created_media_keys = | |
| 90 ContentDecryptionModuleFactory::Create( | |
| 91 // TODO(ddorwin): Address lower in the stack: http://crbug.com/252065 | |
| 92 "webkit-" + key_system, | |
| 93 #if defined(ENABLE_PEPPER_CDMS) | |
| 94 // TODO(ddorwin): Support Pepper-based CDMs: http://crbug.com/250049 | |
| 95 NULL, | |
| 96 NULL, | |
| 97 base::Closure(), | |
| 98 #elif defined(OS_ANDROID) | |
| 99 // TODO(xhwang): Support Android. | |
| 100 NULL, | |
| 101 0, | |
| 102 // TODO(ddorwin): Get the URL for the frame containing the MediaKeys. | |
| 103 GURL(), | |
| 104 #endif // defined(ENABLE_PEPPER_CDMS) | |
| 105 base::Bind(&SessionIdAdapter::OnSessionCreated, weak_this), | |
| 106 base::Bind(&SessionIdAdapter::OnSessionMessage, weak_this), | |
| 107 base::Bind(&SessionIdAdapter::OnSessionReady, weak_this), | |
| 108 base::Bind(&SessionIdAdapter::OnSessionClosed, weak_this), | |
| 109 base::Bind(&SessionIdAdapter::OnSessionError, weak_this)); | |
| 110 if (!created_media_keys) | |
| 111 return false; | |
| 112 | |
| 113 *media_keys = created_media_keys.Pass(); | |
| 114 return true; | |
| 115 } | |
| 116 | |
| 117 uint32 SessionIdAdapter::GenerateSessionId() { | |
| 118 return next_session_id_++; | |
| 119 } | |
| 120 | |
| 121 void SessionIdAdapter::AddSession( | |
| 122 uint32 session_id, | |
| 123 WebContentDecryptionModuleSessionImpl* session) { | |
| 124 DCHECK(sessions_.find(session_id) == sessions_.end()); | |
| 125 sessions_[session_id] = session; | |
| 126 } | |
| 127 | |
| 128 void SessionIdAdapter::RemoveSession(uint32 session_id) { | |
| 129 DCHECK(sessions_.find(session_id) != sessions_.end()); | |
| 130 sessions_.erase(session_id); | |
| 131 } | |
| 132 | |
| 133 void SessionIdAdapter::OnSessionCreated(uint32 session_id, | |
| 134 const std::string& web_session_id) { | |
| 135 GetSession(session_id)->OnSessionCreated(web_session_id); | |
| 136 } | |
| 137 | |
| 138 void SessionIdAdapter::OnSessionMessage(uint32 session_id, | |
| 139 const std::vector<uint8>& message, | |
| 140 const std::string& destination_url) { | |
| 141 GetSession(session_id)->OnSessionMessage(message, destination_url); | |
| 142 } | |
| 143 | |
| 144 void SessionIdAdapter::OnSessionReady(uint32 session_id) { | |
| 145 GetSession(session_id)->OnSessionReady(); | |
| 146 } | |
| 147 | |
| 148 void SessionIdAdapter::OnSessionClosed(uint32 session_id) { | |
| 149 GetSession(session_id)->OnSessionClosed(); | |
| 150 } | |
| 151 | |
| 152 void SessionIdAdapter::OnSessionError(uint32 session_id, | |
| 153 media::MediaKeys::KeyError error_code, | |
| 154 int system_code) { | |
| 155 GetSession(session_id)->OnSessionError(error_code, system_code); | |
| 156 } | |
| 157 | |
| 158 WebContentDecryptionModuleSessionImpl* SessionIdAdapter::GetSession( | |
| 159 uint32 session_id) { | |
| 160 DCHECK(sessions_.find(session_id) != sessions_.end()); | |
| 161 return sessions_[session_id]; | |
| 162 } | |
| 163 | |
| 164 //------------------------------------------------------------------------------ | |
| 165 | |
| 166 WebContentDecryptionModuleImpl* | |
| 167 WebContentDecryptionModuleImpl::Create(const base::string16& key_system) { | |
| 168 // TODO(ddorwin): Guard against this in supported types check and remove this. | 21 // TODO(ddorwin): Guard against this in supported types check and remove this. |
| 169 // Chromium only supports ASCII key systems. | 22 // Chromium only supports ASCII key systems. |
| 170 if (!IsStringASCII(key_system)) { | 23 if (!IsStringASCII(key_system)) { |
| 171 NOTREACHED(); | 24 NOTREACHED(); |
| 172 return NULL; | 25 return NULL; |
| 173 } | 26 } |
| 174 | 27 |
| 175 // SessionIdAdapter creates the MediaKeys so it can provide its callbacks to | 28 scoped_refptr<CdmSessionAdapter> adapter(new CdmSessionAdapter()); |
| 176 // during creation of the MediaKeys. | 29 if (!adapter->Initialize(UTF16ToASCII(key_system))) |
| 177 scoped_ptr<media::MediaKeys> media_keys; | |
| 178 scoped_ptr<SessionIdAdapter> adapter(new SessionIdAdapter()); | |
| 179 if (!adapter->Initialize(UTF16ToASCII(key_system), &media_keys)) | |
| 180 return NULL; | 30 return NULL; |
| 181 | 31 |
| 182 return new WebContentDecryptionModuleImpl(media_keys.Pass(), adapter.Pass()); | 32 return new WebContentDecryptionModuleImpl(adapter); |
| 183 } | 33 } |
| 184 | 34 |
| 185 WebContentDecryptionModuleImpl::WebContentDecryptionModuleImpl( | 35 WebContentDecryptionModuleImpl::WebContentDecryptionModuleImpl( |
| 186 scoped_ptr<media::MediaKeys> media_keys, | 36 scoped_refptr<CdmSessionAdapter> adapter) |
| 187 scoped_ptr<SessionIdAdapter> adapter) | 37 : adapter_(adapter) { |
| 188 : media_keys_(media_keys.Pass()), | |
| 189 adapter_(adapter.Pass()) { | |
| 190 } | 38 } |
| 191 | 39 |
| 192 WebContentDecryptionModuleImpl::~WebContentDecryptionModuleImpl() { | 40 WebContentDecryptionModuleImpl::~WebContentDecryptionModuleImpl() { |
| 193 } | 41 } |
| 194 | 42 |
| 195 // The caller owns the created session. | 43 // The caller owns the created session. |
| 196 blink::WebContentDecryptionModuleSession* | 44 blink::WebContentDecryptionModuleSession* |
| 197 WebContentDecryptionModuleImpl::createSession( | 45 WebContentDecryptionModuleImpl::createSession( |
| 198 blink::WebContentDecryptionModuleSession::Client* client) { | 46 blink::WebContentDecryptionModuleSession::Client* client) { |
| 199 DCHECK(media_keys_); | 47 return adapter_->NewSession(client); |
| 200 uint32 session_id = adapter_->GenerateSessionId(); | |
| 201 WebContentDecryptionModuleSessionImpl* session = | |
| 202 new WebContentDecryptionModuleSessionImpl( | |
| 203 session_id, | |
| 204 media_keys_.get(), | |
| 205 client, | |
| 206 base::Bind(&WebContentDecryptionModuleImpl::OnSessionClosed, | |
| 207 base::Unretained(this))); | |
| 208 | |
| 209 adapter_->AddSession(session_id, session); | |
| 210 return session; | |
| 211 } | 48 } |
| 212 | 49 |
| 213 media::Decryptor* WebContentDecryptionModuleImpl::GetDecryptor() { | 50 media::Decryptor* WebContentDecryptionModuleImpl::GetDecryptor() { |
| 214 return media_keys_->GetDecryptor(); | 51 return adapter_->GetDecryptor(); |
| 215 } | |
| 216 | |
| 217 void WebContentDecryptionModuleImpl::OnSessionClosed(uint32 session_id) { | |
| 218 adapter_->RemoveSession(session_id); | |
| 219 } | 52 } |
| 220 | 53 |
| 221 } // namespace content | 54 } // namespace content |
| OLD | NEW |