1 // Copyright 2014 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/mojo/services/mojo_cdm_service.h"
8 #include "media/base/cdm_config.h"
9 #include "media/base/cdm_factory.h"
10 #include "media/base/cdm_key_information.h"
11 #include "media/base/key_systems.h"
12 #include "media/mojo/services/media_type_converters.h"
13 #include "media/mojo/services/mojo_cdm_service_context.h"
14 #include "mojo/common/common_type_converters.h"
15 #include "mojo/common/url_type_converters.h"
20 using NewSessionMojoCdmPromise
= MojoCdmPromise
<std::string
>;
21 using SimpleMojoCdmPromise
= MojoCdmPromise
<>;
23 MojoCdmService::MojoCdmService(
24 base::WeakPtr
<MojoCdmServiceContext
> context
,
25 mojo::ServiceProvider
* service_provider
,
26 CdmFactory
* cdm_factory
,
27 mojo::InterfaceRequest
<interfaces::ContentDecryptionModule
> request
)
28 : binding_(this, request
.Pass()),
30 service_provider_(service_provider
),
31 cdm_factory_(cdm_factory
),
32 cdm_id_(CdmContext::kInvalidCdmId
),
38 MojoCdmService::~MojoCdmService() {
39 if (cdm_id_
!= CdmContext::kInvalidCdmId
&& context_
)
40 context_
->UnregisterCdm(cdm_id_
);
43 void MojoCdmService::SetClient(
44 interfaces::ContentDecryptionModuleClientPtr client
) {
45 client_
= client
.Pass();
48 void MojoCdmService::Initialize(
49 const mojo::String
& key_system
,
50 const mojo::String
& security_origin
,
51 interfaces::CdmConfigPtr cdm_config
,
53 const mojo::Callback
<void(interfaces::CdmPromiseResultPtr
)>& callback
) {
54 DVLOG(1) << __FUNCTION__
<< ": " << key_system
;
56 DCHECK_NE(CdmContext::kInvalidCdmId
, cdm_id
);
58 auto weak_this
= weak_factory_
.GetWeakPtr();
60 key_system
, GURL(security_origin
), cdm_config
.To
<CdmConfig
>(),
61 base::Bind(&MojoCdmService::OnSessionMessage
, weak_this
),
62 base::Bind(&MojoCdmService::OnSessionClosed
, weak_this
),
63 base::Bind(&MojoCdmService::OnLegacySessionError
, weak_this
),
64 base::Bind(&MojoCdmService::OnSessionKeysChange
, weak_this
),
65 base::Bind(&MojoCdmService::OnSessionExpirationUpdate
, weak_this
),
67 &MojoCdmService::OnCdmCreated
, weak_this
, cdm_id
,
68 base::Passed(make_scoped_ptr(new SimpleMojoCdmPromise(callback
)))));
71 void MojoCdmService::SetServerCertificate(
72 mojo::Array
<uint8_t> certificate_data
,
73 const mojo::Callback
<void(interfaces::CdmPromiseResultPtr
)>& callback
) {
74 DVLOG(2) << __FUNCTION__
;
75 cdm_
->SetServerCertificate(
76 certificate_data
.storage(),
77 make_scoped_ptr(new SimpleMojoCdmPromise(callback
)));
80 void MojoCdmService::CreateSessionAndGenerateRequest(
81 interfaces::ContentDecryptionModule::SessionType session_type
,
82 interfaces::ContentDecryptionModule::InitDataType init_data_type
,
83 mojo::Array
<uint8_t> init_data
,
84 const mojo::Callback
<void(interfaces::CdmPromiseResultPtr
, mojo::String
)>&
86 DVLOG(2) << __FUNCTION__
;
87 cdm_
->CreateSessionAndGenerateRequest(
88 static_cast<MediaKeys::SessionType
>(session_type
),
89 static_cast<EmeInitDataType
>(init_data_type
), init_data
.storage(),
90 make_scoped_ptr(new NewSessionMojoCdmPromise(callback
)));
93 void MojoCdmService::LoadSession(
94 interfaces::ContentDecryptionModule::SessionType session_type
,
95 const mojo::String
& session_id
,
96 const mojo::Callback
<void(interfaces::CdmPromiseResultPtr
, mojo::String
)>&
98 DVLOG(2) << __FUNCTION__
;
99 cdm_
->LoadSession(static_cast<MediaKeys::SessionType
>(session_type
),
100 session_id
.To
<std::string
>(),
101 make_scoped_ptr(new NewSessionMojoCdmPromise(callback
)));
104 void MojoCdmService::UpdateSession(
105 const mojo::String
& session_id
,
106 mojo::Array
<uint8_t> response
,
107 const mojo::Callback
<void(interfaces::CdmPromiseResultPtr
)>& callback
) {
108 DVLOG(2) << __FUNCTION__
;
110 session_id
.To
<std::string
>(), response
.storage(),
111 scoped_ptr
<SimpleCdmPromise
>(new SimpleMojoCdmPromise(callback
)));
114 void MojoCdmService::CloseSession(
115 const mojo::String
& session_id
,
116 const mojo::Callback
<void(interfaces::CdmPromiseResultPtr
)>& callback
) {
117 DVLOG(2) << __FUNCTION__
;
118 cdm_
->CloseSession(session_id
.To
<std::string
>(),
119 make_scoped_ptr(new SimpleMojoCdmPromise(callback
)));
122 void MojoCdmService::RemoveSession(
123 const mojo::String
& session_id
,
124 const mojo::Callback
<void(interfaces::CdmPromiseResultPtr
)>& callback
) {
125 DVLOG(2) << __FUNCTION__
;
126 cdm_
->RemoveSession(session_id
.To
<std::string
>(),
127 make_scoped_ptr(new SimpleMojoCdmPromise(callback
)));
130 void MojoCdmService::GetDecryptor(
131 mojo::InterfaceRequest
<interfaces::Decryptor
> decryptor
) {
135 CdmContext
* MojoCdmService::GetCdmContext() {
136 return cdm_
->GetCdmContext();
139 void MojoCdmService::OnCdmCreated(int cdm_id
,
140 scoped_ptr
<SimpleMojoCdmPromise
> promise
,
141 scoped_ptr
<MediaKeys
> cdm
,
142 const std::string
& error_message
) {
143 // TODO(xhwang): This should not happen when KeySystemInfo is properly
144 // populated. See http://crbug.com/469366
145 if (!cdm
|| !context_
) {
146 promise
->reject(MediaKeys::NOT_SUPPORTED_ERROR
, 0, error_message
);
152 context_
->RegisterCdm(cdm_id_
, this);
156 void MojoCdmService::OnSessionMessage(const std::string
& session_id
,
157 MediaKeys::MessageType message_type
,
158 const std::vector
<uint8_t>& message
,
159 const GURL
& legacy_destination_url
) {
160 DVLOG(2) << __FUNCTION__
;
161 client_
->OnSessionMessage(
162 session_id
, static_cast<interfaces::CdmMessageType
>(message_type
),
163 mojo::Array
<uint8_t>::From(message
),
164 mojo::String::From(legacy_destination_url
));
167 void MojoCdmService::OnSessionKeysChange(const std::string
& session_id
,
168 bool has_additional_usable_key
,
169 CdmKeysInfo keys_info
) {
170 DVLOG(2) << __FUNCTION__
;
171 mojo::Array
<interfaces::CdmKeyInformationPtr
> keys_data
;
172 for (const auto& key
: keys_info
)
173 keys_data
.push_back(interfaces::CdmKeyInformation::From(*key
));
174 client_
->OnSessionKeysChange(session_id
, has_additional_usable_key
,
178 void MojoCdmService::OnSessionExpirationUpdate(
179 const std::string
& session_id
,
180 const base::Time
& new_expiry_time_sec
) {
181 DVLOG(2) << __FUNCTION__
;
182 client_
->OnSessionExpirationUpdate(session_id
,
183 new_expiry_time_sec
.ToDoubleT());
186 void MojoCdmService::OnSessionClosed(const std::string
& session_id
) {
187 DVLOG(2) << __FUNCTION__
;
188 client_
->OnSessionClosed(session_id
);
191 void MojoCdmService::OnLegacySessionError(const std::string
& session_id
,
192 MediaKeys::Exception exception
,
193 uint32_t system_code
,
194 const std::string
& error_message
) {
195 DVLOG(2) << __FUNCTION__
;
196 client_
->OnLegacySessionError(
197 session_id
, static_cast<interfaces::CdmException
>(exception
), system_code
,