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 "media/blink/webcontentdecryptionmodulesession_impl.h"
8 #include "base/callback_helpers.h"
9 #include "base/logging.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.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/cdm_session_adapter.h"
17 #include "media/blink/new_session_cdm_result_promise.h"
18 #include "third_party/WebKit/public/platform/WebString.h"
19 #include "third_party/WebKit/public/platform/WebURL.h"
23 const char kCreateSessionUMAName
[] = "CreateSession";
24 const char kLoadSessionUMAName
[] = "LoadSession";
26 WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl(
27 const scoped_refptr
<CdmSessionAdapter
>& adapter
)
28 : adapter_(adapter
), is_closed_(false), 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
) {
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.
53 void WebContentDecryptionModuleSessionImpl::update(const uint8
* response
,
54 size_t response_length
) {
55 // TODO(jrummell): Remove once blink updated.
59 void WebContentDecryptionModuleSessionImpl::release() {
60 // TODO(jrummell): Remove once blink updated.
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
)) {
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
, 0,
81 blink::WebString::fromUTF8(message
));
85 std::string init_data_type_as_ascii
= base::UTF16ToASCII(init_data_type
);
86 DLOG_IF(WARNING
, init_data_type_as_ascii
.find('/') != std::string::npos
)
87 << "init_data_type '" << init_data_type_as_ascii
88 << "' may be a MIME type";
90 adapter_
->InitializeNewSession(
91 init_data_type_as_ascii
, init_data
,
92 base::saturated_cast
<int>(init_data_length
), MediaKeys::TEMPORARY_SESSION
,
93 scoped_ptr
<NewSessionCdmPromise
>(new NewSessionCdmResultPromise(
94 result
, adapter_
->GetKeySystemUMAPrefix() + kCreateSessionUMAName
,
96 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized
,
97 base::Unretained(this)))));
100 void WebContentDecryptionModuleSessionImpl::load(
101 const blink::WebString
& session_id
,
102 blink::WebContentDecryptionModuleResult result
) {
103 DCHECK(!session_id
.isEmpty());
104 DCHECK(web_session_id_
.empty());
106 adapter_
->LoadSession(
107 base::UTF16ToASCII(session_id
),
108 scoped_ptr
<NewSessionCdmPromise
>(new NewSessionCdmResultPromise(
109 result
, adapter_
->GetKeySystemUMAPrefix() + kLoadSessionUMAName
,
111 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized
,
112 base::Unretained(this)))));
115 void WebContentDecryptionModuleSessionImpl::update(
116 const uint8
* response
,
117 size_t response_length
,
118 blink::WebContentDecryptionModuleResult result
) {
120 DCHECK(!web_session_id_
.empty());
121 adapter_
->UpdateSession(web_session_id_
, response
,
122 base::saturated_cast
<int>(response_length
),
123 scoped_ptr
<SimpleCdmPromise
>(
124 new CdmResultPromise
<>(result
, std::string())));
127 void WebContentDecryptionModuleSessionImpl::close(
128 blink::WebContentDecryptionModuleResult result
) {
129 DCHECK(!web_session_id_
.empty());
130 adapter_
->CloseSession(web_session_id_
,
131 scoped_ptr
<SimpleCdmPromise
>(
132 new CdmResultPromise
<>(result
, std::string())));
135 void WebContentDecryptionModuleSessionImpl::remove(
136 blink::WebContentDecryptionModuleResult result
) {
137 DCHECK(!web_session_id_
.empty());
138 adapter_
->RemoveSession(web_session_id_
,
139 scoped_ptr
<SimpleCdmPromise
>(
140 new CdmResultPromise
<>(result
, std::string())));
143 void WebContentDecryptionModuleSessionImpl::getUsableKeyIds(
144 blink::WebContentDecryptionModuleResult result
) {
145 DCHECK(!web_session_id_
.empty());
146 adapter_
->GetUsableKeyIds(
148 scoped_ptr
<KeyIdsPromise
>(
149 new CdmResultPromise
<KeyIdsVector
>(result
, std::string())));
152 void WebContentDecryptionModuleSessionImpl::release(
153 blink::WebContentDecryptionModuleResult result
) {
157 void WebContentDecryptionModuleSessionImpl::OnSessionMessage(
158 const std::vector
<uint8
>& message
,
159 const GURL
& destination_url
) {
160 DCHECK(client_
) << "Client not set before message event";
161 client_
->message(message
.empty() ? NULL
: &message
[0], message
.size(),
165 void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange(
166 bool has_additional_usable_key
) {
167 // TODO(jrummell): Update this once Blink client supports this.
170 void WebContentDecryptionModuleSessionImpl::OnSessionExpirationUpdate(
171 const base::Time
& new_expiry_time
) {
172 client_
->expirationChanged(new_expiry_time
.ToJsTime());
175 void WebContentDecryptionModuleSessionImpl::OnSessionClosed() {
183 blink::WebContentDecryptionModuleResult::SessionStatus
184 WebContentDecryptionModuleSessionImpl::OnSessionInitialized(
185 const std::string
& web_session_id
) {
186 // CDM will return NULL if the session to be loaded can't be found.
187 if (web_session_id
.empty())
188 return blink::WebContentDecryptionModuleResult::SessionNotFound
;
190 DCHECK(web_session_id_
.empty()) << "Session ID may not be changed once set.";
191 web_session_id_
= web_session_id
;
192 return adapter_
->RegisterSession(web_session_id_
,
193 weak_ptr_factory_
.GetWeakPtr())
194 ? blink::WebContentDecryptionModuleResult::NewSession
195 : blink::WebContentDecryptionModuleResult::SessionAlreadyExists
;