// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MEDIA_MOJO_CLIENTS_MOJO_CDM_H_ #define MEDIA_MOJO_CLIENTS_MOJO_CDM_H_ #include #include #include #include #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" #include "media/base/cdm_context.h" #include "media/base/cdm_initialized_promise.h" #include "media/base/cdm_promise_adapter.h" #include "media/base/cdm_session_tracker.h" #include "media/base/content_decryption_module.h" #include "media/mojo/interfaces/content_decryption_module.mojom.h" #include "mojo/public/cpp/bindings/binding.h" namespace base { class SingleThreadTaskRunner; } namespace media { class MojoDecryptor; // A ContentDecryptionModule that proxies to a mojom::ContentDecryptionModule. // That mojom::ContentDecryptionModule proxies back to the MojoCdm via the // mojom::ContentDecryptionModuleClient interface. class MojoCdm : public ContentDecryptionModule, public CdmContext, public mojom::ContentDecryptionModuleClient { public: using MessageType = CdmMessageType; static void Create( const std::string& key_system, const GURL& security_origin, const CdmConfig& cdm_config, mojom::ContentDecryptionModulePtr remote_cdm, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, const SessionKeysChangeCB& session_keys_change_cb, const SessionExpirationUpdateCB& session_expiration_update_cb, const CdmCreatedCB& cdm_created_cb); // ContentDecryptionModule implementation. void SetServerCertificate(const std::vector& certificate, std::unique_ptr promise) final; void CreateSessionAndGenerateRequest( CdmSessionType session_type, EmeInitDataType init_data_type, const std::vector& init_data, std::unique_ptr promise) final; void LoadSession(CdmSessionType session_type, const std::string& session_id, std::unique_ptr promise) final; void UpdateSession(const std::string& session_id, const std::vector& response, std::unique_ptr promise) final; void CloseSession(const std::string& session_id, std::unique_ptr promise) final; void RemoveSession(const std::string& session_id, std::unique_ptr promise) final; CdmContext* GetCdmContext() final; // CdmContext implementation. Can be called on a different thread. // All GetDecryptor() calls must be made on the same thread. Decryptor* GetDecryptor() final; int GetCdmId() const final; private: MojoCdm(mojom::ContentDecryptionModulePtr remote_cdm, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, const SessionKeysChangeCB& session_keys_change_cb, const SessionExpirationUpdateCB& session_expiration_update_cb); ~MojoCdm() final; void InitializeCdm(const std::string& key_system, const GURL& security_origin, const CdmConfig& cdm_config, std::unique_ptr promise); void OnConnectionError(uint32_t custom_reason, const std::string& description); // mojom::ContentDecryptionModuleClient implementation. void OnSessionMessage(const std::string& session_id, MessageType message_type, const std::vector& message) final; void OnSessionClosed(const std::string& session_id) final; void OnSessionKeysChange( const std::string& session_id, bool has_additional_usable_key, std::vector keys_info) final; void OnSessionExpirationUpdate(const std::string& session_id, double new_expiry_time_sec) final; // Callback for InitializeCdm. void OnCdmInitialized(mojom::CdmPromiseResultPtr result, int cdm_id, mojom::DecryptorPtr decryptor); // Callback when new decryption key is available. void OnKeyAdded(); // Callbacks to handle CDM promises. void OnSimpleCdmPromiseResult(uint32_t promise_id, mojom::CdmPromiseResultPtr result); void OnNewSessionCdmPromiseResult(uint32_t promise_id, mojom::CdmPromiseResultPtr result, const std::string& session_id); base::ThreadChecker thread_checker_; mojom::ContentDecryptionModulePtr remote_cdm_; mojo::Binding binding_; // Protects |cdm_id_|, |decryptor_ptr_|, |decryptor_| and // |decryptor_task_runner_| which could be accessed from other threads. // See CdmContext implementation above. mutable base::Lock lock_; // CDM ID of the remote CDM. Set after initialization is completed. Must not // be invalid if initialization succeeded. int cdm_id_; // The DecryptorPtrInfo exposed by the remote CDM. Set after initialization // is completed and cleared after |decryptor_| is created. May be invalid // after initialization if the CDM doesn't support a Decryptor. mojom::DecryptorPtrInfo decryptor_ptr_info_; // Decryptor based on |decryptor_ptr_|, lazily created in GetDecryptor(). // Since GetDecryptor() can be called on a different thread, use // |decryptor_task_runner_| to bind |decryptor_| to that thread. std::unique_ptr decryptor_; scoped_refptr decryptor_task_runner_; // Callbacks for firing session events. SessionMessageCB session_message_cb_; SessionClosedCB session_closed_cb_; SessionKeysChangeCB session_keys_change_cb_; SessionExpirationUpdateCB session_expiration_update_cb_; // Pending promise for InitializeCdm(). std::unique_ptr pending_init_promise_; // Keep track of current sessions. CdmSessionTracker cdm_session_tracker_; // Keep track of outstanding promises. CdmPromiseAdapter cdm_promise_adapter_; // This must be the last member. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(MojoCdm); }; } // namespace media #endif // MEDIA_MOJO_CLIENTS_MOJO_CDM_H_