1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "key_session_service.h"
17 #include "drm_dfx.h"
18 #include "drm_dfx_utils.h"
19 #include "drm_host_manager.h"
20 #include "drm_log.h"
21 #include "drm_trace.h"
22 #include "drm_error_code.h"
23 #include "ipc_skeleton.h"
24 #include "hitrace/tracechain.h"
25
26 namespace OHOS {
27 namespace DrmStandard {
28 using namespace OHOS::HiviewDFX;
29
MediaKeySessionService(sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> hdiMediaKeySession)30 MediaKeySessionService::MediaKeySessionService(sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> hdiMediaKeySession)
31 {
32 DRM_INFO_LOG("0x%{public}06" PRIXPTR " Instances create.", FAKE_POINTER(this));
33 sessionOperatorsCallback_ = nullptr;
34 hdiMediaKeySession_ = hdiMediaKeySession;
35 }
36
MediaKeySessionService(sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> hdiMediaKeySession,StatisticsInfo statisticsInfo)37 MediaKeySessionService::MediaKeySessionService(sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> hdiMediaKeySession,
38 StatisticsInfo statisticsInfo)
39 {
40 DRM_INFO_LOG("0x%{public}06" PRIXPTR " Instances create.", FAKE_POINTER(this));
41 sessionOperatorsCallback_ = nullptr;
42 hdiMediaKeySession_ = hdiMediaKeySession;
43 statisticsInfo_ = statisticsInfo;
44 }
45
~MediaKeySessionService()46 MediaKeySessionService::~MediaKeySessionService()
47 {
48 DRM_INFO_LOG("~MediaKeySessionService 0x%{public}06" PRIXPTR " Instances destroy.", FAKE_POINTER(this));
49 std::lock_guard<std::recursive_mutex> lock(callbackMutex_);
50 if (sessionOperatorsCallback_ != nullptr) {
51 sessionOperatorsCallback_ = nullptr;
52 }
53 }
54
CloseMediaKeySessionServiceByCallback()55 int32_t MediaKeySessionService::CloseMediaKeySessionServiceByCallback()
56 {
57 DRM_INFO_LOG("CloseMediaKeySessionServiceByCallback enter.");
58 {
59 std::lock_guard<std::recursive_mutex> lock(callbackMutex_);
60 if (sessionOperatorsCallback_ != nullptr) {
61 sessionOperatorsCallback_ = nullptr;
62 }
63 }
64 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
65 int32_t currentPid = IPCSkeleton::GetCallingPid();
66 DRM_DEBUG_LOG("GetCallingPID: %{public}d", currentPid);
67 if (hdiMediaKeySession_ != nullptr) {
68 DRM_INFO_LOG("hdiMediaKeySession_ CloseHdiMediaKeySession");
69 hdiMediaKeySession_->Destroy();
70 hdiMediaKeySession_ = nullptr;
71 }
72
73 return DRM_INNER_ERR_OK;
74 }
75
Release()76 int32_t MediaKeySessionService::Release()
77 {
78 DRM_INFO_LOG("Release enter.");
79 std::lock_guard<std::recursive_mutex> lock(callbackMutex_);
80 int32_t currentPid = IPCSkeleton::GetCallingPid();
81 DRM_DEBUG_LOG("MediaKeySessionService GetCallingPID: %{public}d", currentPid);
82 if (sessionOperatorsCallback_ != nullptr) {
83 sessionOperatorsCallback_->CloseMediaKeySessionService(this);
84 }
85 return DRM_INNER_ERR_OK;
86 }
87
SetMediaKeySessionServiceOperatorsCallback(wptr<IMediaKeySessionServiceOperatorsCallback> callback)88 int32_t MediaKeySessionService::SetMediaKeySessionServiceOperatorsCallback(
89 wptr<IMediaKeySessionServiceOperatorsCallback> callback)
90 {
91 DRM_INFO_LOG("SetMediaKeySessionServiceOperatorsCallback enter.");
92 std::lock_guard<std::recursive_mutex> lock(callbackMutex_);
93 if (callback.promote() == nullptr) {
94 DRM_ERR_LOG("SetMediaKeySessionServiceOperatorsCallback callback is null");
95 return DRM_INNER_ERR_INVALID_VAL;
96 }
97 sessionOperatorsCallback_ = callback;
98 return DRM_INNER_ERR_OK;
99 }
100
GenerateMediaKeyRequest(IMediaKeySessionService::MediaKeyRequestInfo & licenseRequestInfo,IMediaKeySessionService::MediaKeyRequest & licenseRequest)101 int32_t MediaKeySessionService::GenerateMediaKeyRequest(
102 IMediaKeySessionService::MediaKeyRequestInfo &licenseRequestInfo,
103 IMediaKeySessionService::MediaKeyRequest &licenseRequest)
104 {
105 DrmTrace trace("GenerateMediaKeyRequest");
106 DRM_INFO_LOG("GenerateMediaKeyRequest enter.");
107 int32_t ret = DRM_INNER_ERR_OK;
108 OHOS::HDI::Drm::V1_0::MediaKeyRequestInfo hdiMediaKeyRequestInfo;
109 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
110 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
111 "hdiMediaKeySession_ is nullptr!");
112
113 hdiMediaKeyRequestInfo.mediaKeyType = (OHOS::HDI::Drm::V1_0::MediaKeyType)licenseRequestInfo.mediaKeyType;
114 hdiMediaKeyRequestInfo.mimeType = licenseRequestInfo.mimeType;
115 hdiMediaKeyRequestInfo.initData.assign(licenseRequestInfo.initData.begin(), licenseRequestInfo.initData.end());
116 for (std::map<std::string, std::string>::iterator it = licenseRequestInfo.optionalData.begin();
117 it != licenseRequestInfo.optionalData.end(); ++it) {
118 hdiMediaKeyRequestInfo.optionalData.insert(std::make_pair(it->first, it->second));
119 }
120 OHOS::HDI::Drm::V1_0::MediaKeyRequest hdiMediaKeyRequest;
121 mediaKeyType_ = std::to_string(static_cast<int32_t>(licenseRequestInfo.mediaKeyType));
122 auto timeBefore = std::chrono::system_clock::now();
123 ret = hdiMediaKeySession_->GenerateMediaKeyRequest(hdiMediaKeyRequestInfo, hdiMediaKeyRequest);
124 generationDuration_ = CalculateTimeDiff(timeBefore, std::chrono::system_clock::now());
125 if (ret != DRM_INNER_ERR_OK) {
126 generationResult_ = "failed";
127 DRM_ERR_LOG("GenerateMediaKeyRequest failed.");
128 ReportFaultEvent(ret, "GenerateMediaKeyRequest failed", "");
129 return ret;
130 }
131 generationResult_ = "success";
132 licenseRequest.requestType = (IMediaKeySessionService::RequestType)hdiMediaKeyRequest.requestType;
133 licenseRequest.mData.assign(hdiMediaKeyRequest.data.begin(), hdiMediaKeyRequest.data.end());
134 licenseRequest.mDefaultURL = hdiMediaKeyRequest.defaultUrl;
135 return ret;
136 }
137
ProcessMediaKeyResponse(std::vector<uint8_t> & licenseId,std::vector<uint8_t> & licenseResponse)138 int32_t MediaKeySessionService::ProcessMediaKeyResponse(std::vector<uint8_t> &licenseId,
139 std::vector<uint8_t> &licenseResponse)
140 {
141 DrmTrace trace("ProcessMediaKeyResponse");
142 DRM_INFO_LOG("ProcessMediaKeyResponse enter.");
143 int32_t ret = DRM_INNER_ERR_OK;
144 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
145 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
146 "hdiMediaKeySession_ is nullptr!");
147 auto timeBefore = std::chrono::system_clock::now();
148 ret = hdiMediaKeySession_->ProcessMediaKeyResponse(licenseResponse, licenseId);
149 uint32_t processDuration = CalculateTimeDiff(timeBefore, std::chrono::system_clock::now());
150 if (ret != DRM_INNER_ERR_OK) {
151 DRM_ERR_LOG("ProcessMediaKeyResponse failed.");
152 std::string responseString = std::string(reinterpret_cast<const char*>(licenseResponse.data()),
153 licenseResponse.size());
154 ReportFaultEvent(ret, "ProcessMediaKeyResponse failed", responseString);
155 return ret;
156 }
157 struct DownLoadInfo downLoadInfo = InitDownLoadInfo(generationDuration_, generationResult_, processDuration,
158 "success");
159 ReportLicenseBehaviorEvent(statisticsInfo_, mediaKeyType_, downLoadInfo);
160 return ret;
161 }
162
GenerateOfflineReleaseRequest(std::vector<uint8_t> & licenseId,std::vector<uint8_t> & releaseRequest)163 int32_t MediaKeySessionService::GenerateOfflineReleaseRequest(std::vector<uint8_t> &licenseId,
164 std::vector<uint8_t> &releaseRequest)
165 {
166 DRM_INFO_LOG("GenerateOfflineReleaseRequest enter.");
167 int32_t ret = DRM_INNER_ERR_OK;
168 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
169 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
170 "hdiMediaKeySession_ is nullptr!");
171 ret = hdiMediaKeySession_->GetOfflineReleaseRequest(licenseId, releaseRequest);
172 if (ret != DRM_INNER_ERR_OK) {
173 DRM_ERR_LOG("GenerateOfflineReleaseRequest failed.");
174 return ret;
175 }
176 return ret;
177 }
178
ProcessOfflineReleaseResponse(std::vector<uint8_t> & licenseId,std::vector<uint8_t> & releaseResponse)179 int32_t MediaKeySessionService::ProcessOfflineReleaseResponse(std::vector<uint8_t> &licenseId,
180 std::vector<uint8_t> &releaseResponse)
181 {
182 DRM_INFO_LOG("ProcessOfflineReleaseResponse enter.");
183 int32_t ret = DRM_INNER_ERR_OK;
184 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
185 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
186 "hdiMediaKeySession_ is nullptr!");
187
188 ret = hdiMediaKeySession_->ProcessOfflineReleaseResponse(licenseId, releaseResponse);
189 if (ret != DRM_INNER_ERR_OK) {
190 DRM_ERR_LOG("ProcessOfflineReleaseResponse failed.");
191 return ret;
192 }
193 return ret;
194 }
195
CheckMediaKeyStatus(std::map<std::string,std::string> & licenseStatus)196 int32_t MediaKeySessionService::CheckMediaKeyStatus(std::map<std::string, std::string> &licenseStatus)
197 {
198 DRM_INFO_LOG("CheckMediaKeyStatus enter.");
199 int32_t ret = DRM_INNER_ERR_OK;
200 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
201 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
202 "hdiMediaKeySession_ is nullptr!");
203 std::map<std::string, std::string> mp;
204 ret = hdiMediaKeySession_->CheckMediaKeyStatus(mp);
205 if (ret != DRM_INNER_ERR_OK) {
206 DRM_ERR_LOG("CheckMediaKeyStatus failed.");
207 return ret;
208 }
209 for (auto m : mp) {
210 std::string name = m.first;
211 std::string status = m.second;
212 licenseStatus.insert(std::make_pair(name, status));
213 }
214 if (licenseStatus.size() == 0) {
215 DRM_ERR_LOG("CheckMediaKeyStatus licenseStatus is empty.");
216 return DRM_INNER_ERR_BASE;
217 }
218 return ret;
219 }
220
RestoreOfflineMediaKeys(std::vector<uint8_t> & licenseId)221 int32_t MediaKeySessionService::RestoreOfflineMediaKeys(std::vector<uint8_t> &licenseId)
222 {
223 DRM_INFO_LOG("RestoreOfflineMediaKeys enter.");
224 int32_t ret = DRM_INNER_ERR_OK;
225 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
226 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
227 "hdiMediaKeySession_ is nullptr!");
228 ret = hdiMediaKeySession_->RestoreOfflineMediaKeys(licenseId);
229 if (ret != DRM_INNER_ERR_OK) {
230 DRM_ERR_LOG("RestoreOfflineMediaKeys failed.");
231 return ret;
232 }
233 return ret;
234 }
235
ClearMediaKeys()236 int32_t MediaKeySessionService::ClearMediaKeys()
237 {
238 DRM_INFO_LOG("ClearMediaKeys enter.");
239 int32_t ret = DRM_INNER_ERR_OK;
240 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
241 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
242 "hdiMediaKeySession_ is nullptr!");
243 ret = hdiMediaKeySession_->ClearMediaKeys();
244 if (ret != DRM_INNER_ERR_OK) {
245 DRM_ERR_LOG("ClearMediaKeys failed.");
246 return ret;
247 }
248 return ret;
249 }
250
GetContentProtectionLevel(IMediaKeySessionService::ContentProtectionLevel * securityLevel)251 int32_t MediaKeySessionService::GetContentProtectionLevel(
252 IMediaKeySessionService::ContentProtectionLevel *securityLevel)
253 {
254 DRM_INFO_LOG("GetContentProtectionLevel enter.");
255 int32_t ret = DRM_INNER_ERR_OK;
256 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
257 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
258 "hdiMediaKeySession_ is nullptr!");
259 OHOS::HDI::Drm::V1_0::ContentProtectionLevel level;
260 ret = hdiMediaKeySession_->GetContentProtectionLevel(level);
261 if (ret != DRM_INNER_ERR_OK) {
262 DRM_ERR_LOG("GetContentProtectionLevel failed.");
263 return ret;
264 }
265 *securityLevel = (IMediaKeySessionService::ContentProtectionLevel)level;
266 return ret;
267 }
268
GetMediaDecryptModule(sptr<IMediaDecryptModuleService> & decryptModule)269 int32_t MediaKeySessionService::GetMediaDecryptModule(sptr<IMediaDecryptModuleService> &decryptModule)
270 {
271 DrmTrace trace("GetMediaDecryptModule");
272 DRM_INFO_LOG("GetMediaDecryptModule enter.");
273 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
274 if (decryptModule_ != nullptr) {
275 DRM_INFO_LOG("decryptModule already exists.");
276 decryptModule = decryptModule_;
277 return DRM_INNER_ERR_OK;
278 }
279 sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> hdiDecryptModule = nullptr;
280 if (hdiMediaKeySession_ == nullptr) {
281 DRM_ERR_LOG("hdiMediaKeySession_ == nullptr");
282 return DRM_INNER_ERR_INVALID_KEY_SESSION;
283 } else {
284 int32_t retCode = DRM_INNER_ERR_OK;
285 retCode = hdiMediaKeySession_->GetMediaDecryptModule(hdiDecryptModule);
286 if (retCode != DRM_INNER_ERR_OK || hdiDecryptModule == nullptr) {
287 DRM_ERR_LOG("hdiDecryptModule allocation failed.");
288 return DRM_INNER_ERR_BASE;
289 }
290 decryptModule_ = new (std::nothrow) MediaDecryptModuleService(hdiDecryptModule, statisticsInfo_);
291 if (decryptModule_ == nullptr) {
292 DRM_ERR_LOG("New MediaDecryptModuleService allocation failed.");
293 return DRM_INNER_ERR_NO_MEMORY;
294 }
295 decryptModule = decryptModule_;
296 return DRM_INNER_ERR_OK;
297 }
298 }
299
RequireSecureDecoderModule(std::string & mimeType,bool * status)300 int32_t MediaKeySessionService::RequireSecureDecoderModule(std::string &mimeType, bool *status)
301 {
302 DRM_INFO_LOG("RequireSecureDecoderModule enter.");
303
304 int32_t ret = DRM_INNER_ERR_OK;
305 (void)mimeType;
306 (void)status;
307 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
308 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
309 "hdiMediaKeySession_ is nullptr!");
310 bool decoderModuleStatus = false;
311 ret = hdiMediaKeySession_->RequiresSecureDecoderModule(mimeType, decoderModuleStatus);
312 if (ret != DRM_INNER_ERR_OK) {
313 DRM_ERR_LOG("RequireSecureDecoderModule failed.");
314 return ret;
315 }
316 *status = decoderModuleStatus;
317 return ret;
318 }
319
SetCallback(sptr<IMediaKeySessionServiceCallback> & callback)320 int32_t MediaKeySessionService::SetCallback(sptr<IMediaKeySessionServiceCallback> &callback)
321 {
322 DRM_INFO_LOG("SetCallback enter.");
323 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
324 if (callback == nullptr) {
325 DRM_ERR_LOG("SetCallback nullptr , failed.");
326 return DRM_INNER_ERR_BASE;
327 }
328 callback_ = callback;
329 if (hdiMediaKeySession_ != nullptr) {
330 return hdiMediaKeySession_->SetCallback(this);
331 }
332 DRM_ERR_LOG("SetCallback hdiMediaKeySession_ is nullptr , failed.");
333 return DRM_INNER_ERR_OPERATION_NOT_PERMITTED;
334 }
335
SendEvent(OHOS::HDI::Drm::V1_0::EventType eventType,int32_t extra,const std::vector<uint8_t> & data)336 int32_t MediaKeySessionService::SendEvent(OHOS::HDI::Drm::V1_0::EventType eventType, int32_t extra,
337 const std::vector<uint8_t> &data)
338 {
339 DRM_INFO_LOG("SendEvent.");
340 DrmEventType event = static_cast<DrmEventType>(eventType);
341 if (callback_ != nullptr) {
342 return callback_->SendEvent(event, extra, data);
343 }
344 return DRM_INNER_ERR_OPERATION_NOT_PERMITTED;
345 }
346
SendEventKeyChange(const std::map<std::vector<uint8_t>,OHOS::HDI::Drm::V1_0::MediaKeySessionKeyStatus> & keyStatus,bool hasNewGoodLicense)347 int32_t MediaKeySessionService::SendEventKeyChange(
348 const std::map<std::vector<uint8_t>, OHOS::HDI::Drm::V1_0::MediaKeySessionKeyStatus> &keyStatus,
349 bool hasNewGoodLicense)
350 {
351 DRM_INFO_LOG("SendEventKeyChange.");
352 std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> keyStatusMap;
353 for (auto item : keyStatus) {
354 keyStatusMap.insert({ item.first, static_cast<MediaKeySessionKeyStatus>(item.second) });
355 }
356 if (callback_ != nullptr) {
357 return callback_->SendEventKeyChanged(keyStatusMap, hasNewGoodLicense);
358 }
359 return DRM_INNER_ERR_OPERATION_NOT_PERMITTED;
360 }
361
GetDecryptModuleDumpInfo()362 std::string MediaKeySessionService::GetDecryptModuleDumpInfo()
363 {
364 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
365 if (decryptModule_ != nullptr) {
366 return decryptModule_->GetDumpInfo();
367 }
368 return "";
369 }
370 } // DrmStandard
371 } // OHOS