cc: Make picture pile base thread safe.
[chromium-blink-merge.git] / content / renderer / media / webcontentdecryptionmodulesession_impl.cc
blobd9bb455254f9ac02d935511dc32d6a6053ad7645
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.
5 #include "content/renderer/media/webcontentdecryptionmodulesession_impl.h"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/logging.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "content/renderer/media/cdm_session_adapter.h"
13 #include "media/base/cdm_promise.h"
14 #include "media/base/media_keys.h"
15 #include "media/blink/cdm_result_promise.h"
16 #include "media/blink/new_session_cdm_result_promise.h"
17 #include "third_party/WebKit/public/platform/WebURL.h"
19 namespace content {
21 const char kCreateSessionUMAName[] = "CreateSession";
22 const char kLoadSessionUMAName[] = "LoadSession";
24 WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl(
25 const scoped_refptr<CdmSessionAdapter>& adapter)
26 : adapter_(adapter),
27 is_closed_(false),
28 weak_ptr_factory_(this) {
31 WebContentDecryptionModuleSessionImpl::
32 ~WebContentDecryptionModuleSessionImpl() {
33 if (!web_session_id_.empty())
34 adapter_->UnregisterSession(web_session_id_);
37 void WebContentDecryptionModuleSessionImpl::setClientInterface(Client* client) {
38 client_ = client;
41 blink::WebString WebContentDecryptionModuleSessionImpl::sessionId() const {
42 return blink::WebString::fromUTF8(web_session_id_);
45 void WebContentDecryptionModuleSessionImpl::initializeNewSession(
46 const blink::WebString& init_data_type,
47 const uint8* init_data,
48 size_t init_data_length) {
49 // TODO(jrummell): Remove once blink updated.
50 NOTREACHED();
53 void WebContentDecryptionModuleSessionImpl::update(const uint8* response,
54 size_t response_length) {
55 // TODO(jrummell): Remove once blink updated.
56 NOTREACHED();
59 void WebContentDecryptionModuleSessionImpl::release() {
60 // TODO(jrummell): Remove once blink updated.
61 NOTREACHED();
64 void WebContentDecryptionModuleSessionImpl::initializeNewSession(
65 const blink::WebString& init_data_type,
66 const uint8* init_data,
67 size_t init_data_length,
68 const blink::WebString& session_type,
69 blink::WebContentDecryptionModuleResult result) {
70 DCHECK(web_session_id_.empty());
72 // TODO(ddorwin): Guard against this in supported types check and remove this.
73 // Chromium only supports ASCII MIME types.
74 if (!base::IsStringASCII(init_data_type)) {
75 NOTREACHED();
76 std::string message = "The initialization data type " +
77 init_data_type.utf8() +
78 " is not supported by the key system.";
79 result.completeWithError(
80 blink::WebContentDecryptionModuleExceptionNotSupportedError,
82 blink::WebString::fromUTF8(message));
83 return;
86 std::string init_data_type_as_ascii = base::UTF16ToASCII(init_data_type);
87 DLOG_IF(WARNING, init_data_type_as_ascii.find('/') != std::string::npos)
88 << "init_data_type '" << init_data_type_as_ascii
89 << "' may be a MIME type";
91 adapter_->InitializeNewSession(
92 init_data_type_as_ascii,
93 init_data,
94 init_data_length,
95 media::MediaKeys::TEMPORARY_SESSION,
96 scoped_ptr<media::NewSessionCdmPromise>(
97 new media::NewSessionCdmResultPromise(
98 result,
99 adapter_->GetKeySystemUMAPrefix() + kCreateSessionUMAName,
100 base::Bind(
101 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized,
102 base::Unretained(this)))));
105 void WebContentDecryptionModuleSessionImpl::load(
106 const blink::WebString& session_id,
107 blink::WebContentDecryptionModuleResult result) {
108 DCHECK(!session_id.isEmpty());
109 DCHECK(web_session_id_.empty());
111 adapter_->LoadSession(
112 base::UTF16ToASCII(session_id),
113 scoped_ptr<media::NewSessionCdmPromise>(
114 new media::NewSessionCdmResultPromise(
115 result,
116 adapter_->GetKeySystemUMAPrefix() + kLoadSessionUMAName,
117 base::Bind(
118 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized,
119 base::Unretained(this)))));
122 void WebContentDecryptionModuleSessionImpl::update(
123 const uint8* response,
124 size_t response_length,
125 blink::WebContentDecryptionModuleResult result) {
126 DCHECK(response);
127 DCHECK(!web_session_id_.empty());
128 adapter_->UpdateSession(
129 web_session_id_,
130 response,
131 response_length,
132 scoped_ptr<media::SimpleCdmPromise>(
133 new media::CdmResultPromise<>(result, std::string())));
136 void WebContentDecryptionModuleSessionImpl::close(
137 blink::WebContentDecryptionModuleResult result) {
138 DCHECK(!web_session_id_.empty());
139 adapter_->CloseSession(
140 web_session_id_,
141 scoped_ptr<media::SimpleCdmPromise>(
142 new media::CdmResultPromise<>(result, std::string())));
145 void WebContentDecryptionModuleSessionImpl::remove(
146 blink::WebContentDecryptionModuleResult result) {
147 DCHECK(!web_session_id_.empty());
148 adapter_->RemoveSession(
149 web_session_id_,
150 scoped_ptr<media::SimpleCdmPromise>(
151 new media::CdmResultPromise<>(result, std::string())));
154 void WebContentDecryptionModuleSessionImpl::getUsableKeyIds(
155 blink::WebContentDecryptionModuleResult result) {
156 DCHECK(!web_session_id_.empty());
157 adapter_->GetUsableKeyIds(
158 web_session_id_,
159 scoped_ptr<media::KeyIdsPromise>(
160 new media::CdmResultPromise<media::KeyIdsVector>(result,
161 std::string())));
164 void WebContentDecryptionModuleSessionImpl::release(
165 blink::WebContentDecryptionModuleResult result) {
166 close(result);
169 void WebContentDecryptionModuleSessionImpl::OnSessionMessage(
170 const std::vector<uint8>& message,
171 const GURL& destination_url) {
172 DCHECK(client_) << "Client not set before message event";
173 client_->message(
174 message.empty() ? NULL : &message[0], message.size(), destination_url);
177 void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange(
178 bool has_additional_usable_key) {
179 // TODO(jrummell): Update this once Blink client supports this.
182 void WebContentDecryptionModuleSessionImpl::OnSessionExpirationUpdate(
183 const base::Time& new_expiry_time) {
184 client_->expirationChanged(new_expiry_time.ToJsTime());
187 void WebContentDecryptionModuleSessionImpl::OnSessionReady() {
188 client_->ready();
191 void WebContentDecryptionModuleSessionImpl::OnSessionClosed() {
192 if (is_closed_)
193 return;
195 is_closed_ = true;
196 client_->close();
199 void WebContentDecryptionModuleSessionImpl::OnSessionError(
200 media::MediaKeys::Exception exception_code,
201 uint32 system_code,
202 const std::string& error_message) {
203 // Convert |exception_code| back to MediaKeyErrorCode if possible.
204 // TODO(jrummell): Update this conversion when promises flow
205 // back into blink:: (as blink:: will have its own error definition).
206 switch (exception_code) {
207 case media::MediaKeys::CLIENT_ERROR:
208 client_->error(Client::MediaKeyErrorCodeClient, system_code);
209 break;
210 default:
211 // This will include all other CDM4 errors and any error generated
212 // by CDM5 or later.
213 client_->error(Client::MediaKeyErrorCodeUnknown, system_code);
214 break;
218 blink::WebContentDecryptionModuleResult::SessionStatus
219 WebContentDecryptionModuleSessionImpl::OnSessionInitialized(
220 const std::string& web_session_id) {
221 // CDM will return NULL if the session to be loaded can't be found.
222 if (web_session_id.empty())
223 return blink::WebContentDecryptionModuleResult::SessionNotFound;
225 DCHECK(web_session_id_.empty()) << "Session ID may not be changed once set.";
226 web_session_id_ = web_session_id;
227 return adapter_->RegisterSession(web_session_id_,
228 weak_ptr_factory_.GetWeakPtr())
229 ? blink::WebContentDecryptionModuleResult::NewSession
230 : blink::WebContentDecryptionModuleResult::SessionAlreadyExists;
233 } // namespace content