| // Copyright 2017 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "cobalt/dom/eme/media_keys.h" |
| |
| #include "base/bind.h" |
| #include "cobalt/dom/dom_exception.h" |
| #include "cobalt/dom/eme/eme_helpers.h" |
| #include "cobalt/dom/eme/media_key_session.h" |
| |
| namespace cobalt { |
| namespace dom { |
| namespace eme { |
| |
| MediaKeys::MediaKeys(const std::string& key_system, |
| script::ScriptValueFactory* script_value_factory) |
| : script_value_factory_(script_value_factory), |
| drm_system_(new media::DrmSystem(key_system.c_str())) {} |
| |
| // See https://www.w3.org/TR/encrypted-media/#dom-mediakeys-createsession. |
| scoped_refptr<MediaKeySession> MediaKeys::CreateSession( |
| MediaKeySessionType session_type, script::ExceptionState* exception_state) { |
| // 1. If this object's supported session types value does not contain |
| // sessionType, throw a NotSupportedError. |
| if (session_type != kMediaKeySessionTypeTemporary) { |
| DOMException::Raise(DOMException::kNotSupportedErr, exception_state); |
| return NULL; |
| } |
| |
| // 3. Let session be a new MediaKeySession object. |
| // |
| // |MediaKeys| are passed to |MediaKeySession| as weak pointer because the |
| // order of destruction is not guaranteed due to JavaScript memory management. |
| scoped_refptr<MediaKeySession> session(new MediaKeySession( |
| drm_system_, script_value_factory_, |
| base::Bind(&MediaKeys::OnSessionClosed, AsWeakPtr()))); |
| open_sessions_.push_back(session); |
| return session; |
| } |
| |
| MediaKeys::BoolPromiseHandle MediaKeys::SetServerCertificate( |
| const BufferSource& server_certificate) { |
| BoolPromiseHandle promise = script_value_factory_->CreateBasicPromise<bool>(); |
| |
| // 1. If the Key System implementation represented by this object's cdm |
| // implementation value does not support server certificates, return a |
| // promise resolved with false. |
| if (!drm_system_->IsServerCertificateUpdatable()) { |
| promise->Resolve(false); |
| return promise; |
| } |
| |
| // 2. If serverCertificate is an empty array, return a promise rejected with a |
| // newly created TypeError. |
| const uint8* server_certificate_buffer; |
| int server_certificate_buffer_size = 0; |
| GetBufferAndSize(server_certificate, &server_certificate_buffer, |
| &server_certificate_buffer_size); |
| |
| if (server_certificate_buffer_size == 0) { |
| promise->Reject(script::kTypeError); |
| return promise; |
| } |
| |
| // 3. Let certificate be a copy of the contents of the serverCertificate |
| // parameter. |
| // 4. Let promise be a new promise. |
| // 5. Run the following steps in parallel: |
| // 5.1 Let sanitized certificate be a validated and/or sanitized version of |
| // certificate. |
| // 5.2 Use this object's cdm instance to process sanitized certificate. |
| drm_system_->UpdateServerCertificate( |
| server_certificate_buffer, server_certificate_buffer_size, |
| base::Bind(&MediaKeys::OnServerCertificateUpdated, base::AsWeakPtr(this), |
| base::Owned(new BoolPromiseValue::Reference(this, promise)))); |
| |
| // 5.3 and 5.4 are pending processing in OnServerCertificateUpdated(). |
| // 6. Return promise. |
| return promise; |
| } |
| |
| void MediaKeys::OnSessionClosed(MediaKeySession* session) { |
| // Erase-remove idiom, see |
| // https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom. |
| open_sessions_.erase( |
| std::remove(open_sessions_.begin(), open_sessions_.end(), session), |
| open_sessions_.end()); |
| } |
| |
| void MediaKeys::OnServerCertificateUpdated( |
| BoolPromiseValue::Reference* promise_reference, SbDrmStatus status, |
| const std::string& error_message) { |
| // 5.3 If the preceding step failed, resolve promise with a new DOMException |
| // whose name is the appropriate error name. |
| if (status != kSbDrmStatusSuccess) { |
| RejectPromise(promise_reference, status, error_message); |
| return; |
| } |
| // 5.4 Resolve promise with true. |
| promise_reference->value().Resolve(true); |
| } |
| |
| void MediaKeys::TraceMembers(script::Tracer* tracer) { |
| tracer->TraceItems(open_sessions_); |
| } |
| |
| MediaKeys::~MediaKeys() {} |
| |
| } // namespace eme |
| } // namespace dom |
| } // namespace cobalt |