Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2023 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #include "CdmBackend.h"
21 :
22 85 : CdmBackend::CdmBackend(const std::string &keySystem,
23 : const std::shared_ptr<firebolt::rialto::IMediaKeysClient> &mediaKeysClient,
24 85 : const std::shared_ptr<firebolt::rialto::IMediaKeysFactory> &mediaKeysFactory)
25 170 : : m_log{"CdmBackend"}, m_appState{firebolt::rialto::ApplicationState::UNKNOWN}, m_keySystem{keySystem},
26 255 : m_mediaKeysClient{mediaKeysClient}, m_mediaKeysFactory{mediaKeysFactory}
27 : {
28 85 : }
29 :
30 46 : void CdmBackend::notifyApplicationState(firebolt::rialto::ApplicationState state)
31 : {
32 46 : std::unique_lock<std::mutex> lock{m_mutex};
33 46 : if (state == m_appState)
34 : {
35 1 : return;
36 : }
37 45 : if (firebolt::rialto::ApplicationState::RUNNING == state)
38 : {
39 42 : m_log << info << "Rialto state changed to: RUNNING";
40 42 : if (createMediaKeys())
41 : {
42 42 : m_appState = state;
43 42 : m_cv.notify_one();
44 : }
45 : }
46 : else
47 : {
48 3 : m_log << info << "Rialto state changed to: INACTIVE";
49 3 : m_mediaKeys.reset();
50 3 : m_appState = state;
51 : }
52 46 : }
53 :
54 23 : bool CdmBackend::initialize(const firebolt::rialto::ApplicationState &initialState)
55 : {
56 23 : std::unique_lock<std::mutex> lock{m_mutex};
57 23 : if (firebolt::rialto::ApplicationState::UNKNOWN != m_appState)
58 : {
59 : // CdmBackend initialized by Rialto Client thread in notifyApplicationState()
60 1 : return true;
61 : }
62 22 : if (firebolt::rialto::ApplicationState::RUNNING == initialState)
63 : {
64 20 : if (!createMediaKeys())
65 : {
66 2 : return false;
67 : }
68 : }
69 20 : m_log << info << "CdmBackend initialized in "
70 20 : << (firebolt::rialto::ApplicationState::RUNNING == initialState ? "RUNNING" : "INACTIVE") << " state";
71 20 : m_appState = initialState;
72 20 : return true;
73 23 : }
74 :
75 3 : bool CdmBackend::selectKeyId(int32_t keySessionId, const std::vector<uint8_t> &keyId)
76 : {
77 3 : std::unique_lock<std::mutex> lock{m_mutex};
78 3 : if (!m_mediaKeys)
79 : {
80 1 : return false;
81 : }
82 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->selectKeyId(keySessionId, keyId);
83 3 : }
84 :
85 3 : bool CdmBackend::containsKey(int32_t keySessionId, const std::vector<uint8_t> &keyId)
86 : {
87 3 : std::unique_lock<std::mutex> lock{m_mutex};
88 3 : if (!m_mediaKeys)
89 : {
90 1 : return false;
91 : }
92 2 : return m_mediaKeys->containsKey(keySessionId, keyId);
93 3 : }
94 :
95 3 : bool CdmBackend::createKeySession(firebolt::rialto::KeySessionType sessionType, bool isLDL, int32_t &keySessionId)
96 : {
97 3 : std::unique_lock<std::mutex> lock{m_mutex};
98 : // Sometimes app tries to create session before reaching RUNNING state. We have to wait for it.
99 3 : m_cv.wait_for(lock, std::chrono::seconds(1),
100 4 : [this]() { return firebolt::rialto::ApplicationState::RUNNING == m_appState; });
101 3 : if (!m_mediaKeys)
102 : {
103 1 : return false;
104 : }
105 : return firebolt::rialto::MediaKeyErrorStatus::OK ==
106 2 : m_mediaKeys->createKeySession(sessionType, m_mediaKeysClient, isLDL, keySessionId);
107 3 : }
108 :
109 3 : bool CdmBackend::generateRequest(int32_t keySessionId, firebolt::rialto::InitDataType initDataType,
110 : const std::vector<uint8_t> &initData)
111 : {
112 3 : std::unique_lock<std::mutex> lock{m_mutex};
113 3 : if (!m_mediaKeys)
114 : {
115 1 : return false;
116 : }
117 : return firebolt::rialto::MediaKeyErrorStatus::OK ==
118 2 : m_mediaKeys->generateRequest(keySessionId, initDataType, initData);
119 3 : }
120 :
121 3 : bool CdmBackend::loadSession(int32_t keySessionId)
122 : {
123 3 : std::unique_lock<std::mutex> lock{m_mutex};
124 3 : if (!m_mediaKeys)
125 : {
126 1 : return false;
127 : }
128 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->loadSession(keySessionId);
129 3 : }
130 :
131 3 : bool CdmBackend::updateSession(int32_t keySessionId, const std::vector<uint8_t> &responseData)
132 : {
133 3 : std::unique_lock<std::mutex> lock{m_mutex};
134 3 : if (!m_mediaKeys)
135 : {
136 1 : return false;
137 : }
138 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->updateSession(keySessionId, responseData);
139 3 : }
140 :
141 3 : bool CdmBackend::setDrmHeader(int32_t keySessionId, const std::vector<uint8_t> &requestData)
142 : {
143 3 : std::unique_lock<std::mutex> lock{m_mutex};
144 3 : if (!m_mediaKeys)
145 : {
146 1 : return false;
147 : }
148 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->setDrmHeader(keySessionId, requestData);
149 3 : }
150 :
151 3 : bool CdmBackend::closeKeySession(int32_t keySessionId)
152 : {
153 3 : std::unique_lock<std::mutex> lock{m_mutex};
154 3 : if (!m_mediaKeys)
155 : {
156 1 : return false;
157 : }
158 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->closeKeySession(keySessionId);
159 3 : }
160 :
161 3 : bool CdmBackend::removeKeySession(int32_t keySessionId)
162 : {
163 3 : std::unique_lock<std::mutex> lock{m_mutex};
164 3 : if (!m_mediaKeys)
165 : {
166 1 : return false;
167 : }
168 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->removeKeySession(keySessionId);
169 3 : }
170 :
171 5 : bool CdmBackend::deleteDrmStore()
172 : {
173 5 : std::unique_lock<std::mutex> lock{m_mutex};
174 5 : if (!m_mediaKeys)
175 : {
176 1 : return false;
177 : }
178 4 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->deleteDrmStore();
179 5 : }
180 :
181 5 : bool CdmBackend::deleteKeyStore()
182 : {
183 5 : std::unique_lock<std::mutex> lock{m_mutex};
184 5 : if (!m_mediaKeys)
185 : {
186 1 : return false;
187 : }
188 4 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->deleteKeyStore();
189 5 : }
190 :
191 5 : bool CdmBackend::getDrmStoreHash(std::vector<unsigned char> &drmStoreHash)
192 : {
193 5 : std::unique_lock<std::mutex> lock{m_mutex};
194 5 : if (!m_mediaKeys)
195 : {
196 1 : return false;
197 : }
198 4 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->getDrmStoreHash(drmStoreHash);
199 5 : }
200 :
201 5 : bool CdmBackend::getKeyStoreHash(std::vector<unsigned char> &keyStoreHash)
202 : {
203 5 : std::unique_lock<std::mutex> lock{m_mutex};
204 5 : if (!m_mediaKeys)
205 : {
206 1 : return false;
207 : }
208 4 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->getKeyStoreHash(keyStoreHash);
209 5 : }
210 :
211 5 : bool CdmBackend::getLdlSessionsLimit(uint32_t &ldlLimit)
212 : {
213 5 : std::unique_lock<std::mutex> lock{m_mutex};
214 5 : if (!m_mediaKeys)
215 : {
216 1 : return false;
217 : }
218 4 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->getLdlSessionsLimit(ldlLimit);
219 5 : }
220 :
221 3 : bool CdmBackend::getLastDrmError(int32_t keySessionId, uint32_t &errorCode)
222 : {
223 3 : std::unique_lock<std::mutex> lock{m_mutex};
224 3 : if (!m_mediaKeys)
225 : {
226 1 : return false;
227 : }
228 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->getLastDrmError(keySessionId, errorCode);
229 3 : }
230 :
231 5 : bool CdmBackend::getDrmTime(uint64_t &drmTime)
232 : {
233 5 : std::unique_lock<std::mutex> lock{m_mutex};
234 5 : if (!m_mediaKeys)
235 : {
236 1 : return false;
237 : }
238 4 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->getDrmTime(drmTime);
239 5 : }
240 :
241 3 : bool CdmBackend::getCdmKeySessionId(int32_t keySessionId, std::string &cdmKeySessionId)
242 : {
243 3 : std::unique_lock<std::mutex> lock{m_mutex};
244 3 : if (!m_mediaKeys)
245 : {
246 1 : return false;
247 : }
248 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->getCdmKeySessionId(keySessionId, cdmKeySessionId);
249 3 : }
250 :
251 3 : bool CdmBackend::releaseKeySession(int32_t keySessionId)
252 : {
253 3 : std::unique_lock<std::mutex> lock{m_mutex};
254 3 : if (!m_mediaKeys)
255 : {
256 1 : return false;
257 : }
258 2 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->releaseKeySession(keySessionId);
259 3 : }
260 :
261 62 : bool CdmBackend::createMediaKeys()
262 : {
263 62 : if (!m_mediaKeysFactory)
264 : {
265 1 : m_log << error << "Failed to initialize media keys - not possible to create factory";
266 1 : return false;
267 : }
268 :
269 61 : m_mediaKeys = m_mediaKeysFactory->createMediaKeys(m_keySystem);
270 61 : if (!m_mediaKeys)
271 : {
272 1 : m_log << error << "Failed to initialize media keys - not possible to create media keys";
273 1 : return false;
274 : }
275 60 : return true;
276 : }
277 :
278 5 : bool CdmBackend::getMetricSystemData(std::vector<uint8_t> &buffer)
279 : {
280 5 : std::unique_lock<std::mutex> lock{m_mutex};
281 5 : if (!m_mediaKeys)
282 : {
283 1 : return false;
284 : }
285 4 : return firebolt::rialto::MediaKeyErrorStatus::OK == m_mediaKeys->getMetricSystemData(buffer);
286 5 : }
|