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_->CreateSession(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 |