Remove no longer needed toolbar layer method.
[chromium-blink-merge.git] / media / blink / webcontentdecryptionmodulesession_impl.cc
blobe458c55cc7549255f25b6d8984958cb35f385842
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 "webcontentdecryptionmodulesession_impl.h"
7 #include "base/bind.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_key_information.h"
14 #include "media/base/cdm_promise.h"
15 #include "media/base/key_systems.h"
16 #include "media/base/media_keys.h"
17 #include "media/blink/cdm_result_promise.h"
18 #include "media/blink/cdm_session_adapter.h"
19 #include "media/blink/new_session_cdm_result_promise.h"
20 #include "third_party/WebKit/public/platform/WebData.h"
21 #include "third_party/WebKit/public/platform/WebEncryptedMediaKeyInformation.h"
22 #include "third_party/WebKit/public/platform/WebString.h"
23 #include "third_party/WebKit/public/platform/WebURL.h"
24 #include "third_party/WebKit/public/platform/WebVector.h"
26 namespace media {
28 const char kCloseSessionUMAName[] = "CloseSession";
29 const char kGenerateRequestUMAName[] = "GenerateRequest";
30 const char kLoadSessionUMAName[] = "LoadSession";
31 const char kRemoveSessionUMAName[] = "RemoveSession";
32 const char kUpdateSessionUMAName[] = "UpdateSession";
34 static blink::WebContentDecryptionModuleSession::Client::MessageType
35 convertMessageType(MediaKeys::MessageType message_type) {
36 switch (message_type) {
37 case media::MediaKeys::LICENSE_REQUEST:
38 return blink::WebContentDecryptionModuleSession::Client::MessageType::
39 LicenseRequest;
40 case media::MediaKeys::LICENSE_RENEWAL:
41 return blink::WebContentDecryptionModuleSession::Client::MessageType::
42 LicenseRenewal;
43 case media::MediaKeys::LICENSE_RELEASE:
44 return blink::WebContentDecryptionModuleSession::Client::MessageType::
45 LicenseRelease;
48 NOTREACHED();
49 return blink::WebContentDecryptionModuleSession::Client::MessageType::
50 LicenseRequest;
53 static blink::WebEncryptedMediaKeyInformation::KeyStatus convertStatus(
54 media::CdmKeyInformation::KeyStatus status) {
55 switch (status) {
56 case media::CdmKeyInformation::USABLE:
57 return blink::WebEncryptedMediaKeyInformation::KeyStatus::Usable;
58 case media::CdmKeyInformation::INTERNAL_ERROR:
59 return blink::WebEncryptedMediaKeyInformation::KeyStatus::InternalError;
60 case media::CdmKeyInformation::EXPIRED:
61 return blink::WebEncryptedMediaKeyInformation::KeyStatus::Expired;
62 case media::CdmKeyInformation::OUTPUT_NOT_ALLOWED:
63 return blink::WebEncryptedMediaKeyInformation::KeyStatus::
64 OutputNotAllowed;
67 NOTREACHED();
68 return blink::WebEncryptedMediaKeyInformation::KeyStatus::InternalError;
71 WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl(
72 const scoped_refptr<CdmSessionAdapter>& adapter)
73 : adapter_(adapter), is_closed_(false), weak_ptr_factory_(this) {
76 WebContentDecryptionModuleSessionImpl::
77 ~WebContentDecryptionModuleSessionImpl() {
78 if (!session_id_.empty())
79 adapter_->UnregisterSession(session_id_);
82 void WebContentDecryptionModuleSessionImpl::setClientInterface(Client* client) {
83 client_ = client;
86 blink::WebString WebContentDecryptionModuleSessionImpl::sessionId() const {
87 return blink::WebString::fromUTF8(session_id_);
90 void WebContentDecryptionModuleSessionImpl::initializeNewSession(
91 blink::WebEncryptedMediaInitDataType init_data_type,
92 const unsigned char* init_data,
93 size_t init_data_length,
94 blink::WebEncryptedMediaSessionType session_type,
95 blink::WebContentDecryptionModuleResult result) {
96 DCHECK(session_id_.empty());
98 // TODO(jrummell): |init_data_type| should be an enum all the way through
99 // Chromium. http://crbug.com/417440
100 std::string init_data_type_as_ascii = "unknown";
101 switch (init_data_type) {
102 case blink::WebEncryptedMediaInitDataType::Cenc:
103 init_data_type_as_ascii = "cenc";
104 break;
105 case blink::WebEncryptedMediaInitDataType::Keyids:
106 init_data_type_as_ascii = "keyids";
107 break;
108 case blink::WebEncryptedMediaInitDataType::Webm:
109 init_data_type_as_ascii = "webm";
110 break;
111 case blink::WebEncryptedMediaInitDataType::Unknown:
112 NOTREACHED() << "unexpected init_data_type";
113 break;
116 // Step 5 from https://w3c.github.io/encrypted-media/#generateRequest.
117 // 5. If the Key System implementation represented by this object's cdm
118 // implementation value does not support initDataType as an Initialization
119 // Data Type, return a promise rejected with a new DOMException whose name
120 // is NotSupportedError. String comparison is case-sensitive.
121 if (!IsSupportedKeySystemWithInitDataType(adapter_->GetKeySystem(),
122 init_data_type_as_ascii)) {
123 std::string message = "The initialization data type " +
124 init_data_type_as_ascii +
125 " is not supported by the key system.";
126 result.completeWithError(
127 blink::WebContentDecryptionModuleExceptionNotSupportedError, 0,
128 blink::WebString::fromUTF8(message));
129 return;
132 MediaKeys::SessionType session_type_enum = MediaKeys::TEMPORARY_SESSION;
133 switch (session_type) {
134 case blink::WebEncryptedMediaSessionType::Temporary:
135 session_type_enum = MediaKeys::TEMPORARY_SESSION;
136 break;
137 case blink::WebEncryptedMediaSessionType::PersistentLicense:
138 session_type_enum = MediaKeys::PERSISTENT_LICENSE_SESSION;
139 break;
140 case blink::WebEncryptedMediaSessionType::PersistentReleaseMessage:
141 session_type_enum = MediaKeys::PERSISTENT_RELEASE_MESSAGE_SESSION;
142 break;
143 case blink::WebEncryptedMediaSessionType::Unknown:
144 NOTREACHED() << "unexpected session_type";
145 break;
148 adapter_->InitializeNewSession(
149 init_data_type_as_ascii, init_data,
150 base::saturated_cast<int>(init_data_length), session_type_enum,
151 scoped_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise(
152 result, adapter_->GetKeySystemUMAPrefix() + kGenerateRequestUMAName,
153 base::Bind(
154 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized,
155 base::Unretained(this)))));
158 // TODO(jrummell): Remove this. http://crbug.com/418239.
159 void WebContentDecryptionModuleSessionImpl::initializeNewSession(
160 const blink::WebString& init_data_type,
161 const uint8* init_data,
162 size_t init_data_length,
163 const blink::WebString& session_type,
164 blink::WebContentDecryptionModuleResult result) {
165 NOTREACHED();
168 void WebContentDecryptionModuleSessionImpl::load(
169 const blink::WebString& session_id,
170 blink::WebContentDecryptionModuleResult result) {
171 DCHECK(!session_id.isEmpty());
172 DCHECK(session_id_.empty());
174 // TODO(jrummell): Now that there are 2 types of persistent sessions, the
175 // session type should be passed from blink. Type should also be passed in the
176 // constructor (and removed from initializeNewSession()).
177 adapter_->LoadSession(
178 MediaKeys::PERSISTENT_LICENSE_SESSION, base::UTF16ToASCII(session_id),
179 scoped_ptr<NewSessionCdmPromise>(new NewSessionCdmResultPromise(
180 result, adapter_->GetKeySystemUMAPrefix() + kLoadSessionUMAName,
181 base::Bind(
182 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized,
183 base::Unretained(this)))));
186 void WebContentDecryptionModuleSessionImpl::update(
187 const uint8* response,
188 size_t response_length,
189 blink::WebContentDecryptionModuleResult result) {
190 DCHECK(response);
191 DCHECK(!session_id_.empty());
192 adapter_->UpdateSession(
193 session_id_, response, base::saturated_cast<int>(response_length),
194 scoped_ptr<SimpleCdmPromise>(new CdmResultPromise<>(
195 result, adapter_->GetKeySystemUMAPrefix() + kUpdateSessionUMAName)));
198 void WebContentDecryptionModuleSessionImpl::close(
199 blink::WebContentDecryptionModuleResult result) {
200 DCHECK(!session_id_.empty());
201 adapter_->CloseSession(
202 session_id_,
203 scoped_ptr<SimpleCdmPromise>(new CdmResultPromise<>(
204 result, adapter_->GetKeySystemUMAPrefix() + kCloseSessionUMAName)));
207 void WebContentDecryptionModuleSessionImpl::remove(
208 blink::WebContentDecryptionModuleResult result) {
209 DCHECK(!session_id_.empty());
210 adapter_->RemoveSession(
211 session_id_,
212 scoped_ptr<SimpleCdmPromise>(new CdmResultPromise<>(
213 result, adapter_->GetKeySystemUMAPrefix() + kRemoveSessionUMAName)));
216 void WebContentDecryptionModuleSessionImpl::OnSessionMessage(
217 MediaKeys::MessageType message_type,
218 const std::vector<uint8>& message) {
219 DCHECK(client_) << "Client not set before message event";
220 client_->message(convertMessageType(message_type),
221 message.empty() ? NULL : &message[0], message.size());
224 void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange(
225 bool has_additional_usable_key,
226 CdmKeysInfo keys_info) {
227 blink::WebVector<blink::WebEncryptedMediaKeyInformation> keys(
228 keys_info.size());
229 for (size_t i = 0; i < keys_info.size(); ++i) {
230 const auto& key_info = keys_info[i];
231 keys[i].setId(blink::WebData(reinterpret_cast<char*>(&key_info->key_id[0]),
232 key_info->key_id.size()));
233 keys[i].setStatus(convertStatus(key_info->status));
234 keys[i].setSystemCode(key_info->system_code);
237 // Now send the event to blink.
238 client_->keysStatusesChange(keys, has_additional_usable_key);
241 void WebContentDecryptionModuleSessionImpl::OnSessionExpirationUpdate(
242 const base::Time& new_expiry_time) {
243 client_->expirationChanged(new_expiry_time.ToJsTime());
246 void WebContentDecryptionModuleSessionImpl::OnSessionClosed() {
247 if (is_closed_)
248 return;
250 is_closed_ = true;
251 client_->close();
254 blink::WebContentDecryptionModuleResult::SessionStatus
255 WebContentDecryptionModuleSessionImpl::OnSessionInitialized(
256 const std::string& session_id) {
257 // CDM will return NULL if the session to be loaded can't be found.
258 if (session_id.empty())
259 return blink::WebContentDecryptionModuleResult::SessionNotFound;
261 DCHECK(session_id_.empty()) << "Session ID may not be changed once set.";
262 session_id_ = session_id;
263 return adapter_->RegisterSession(session_id_, weak_ptr_factory_.GetWeakPtr())
264 ? blink::WebContentDecryptionModuleResult::NewSession
265 : blink::WebContentDecryptionModuleResult::SessionAlreadyExists;
268 } // namespace media