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 statisticsInfo_.targetVersion = 0;
36 }
37
MediaKeySessionService(sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> hdiMediaKeySession,StatisticsInfo statisticsInfo)38 MediaKeySessionService::MediaKeySessionService(sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession> hdiMediaKeySession,
39 StatisticsInfo statisticsInfo)
40 {
41 DRM_INFO_LOG("0x%{public}06" PRIXPTR " Instances create.", FAKE_POINTER(this));
42 sessionOperatorsCallback_ = nullptr;
43 hdiMediaKeySession_ = hdiMediaKeySession;
44 statisticsInfo_ = statisticsInfo;
45 }
46
~MediaKeySessionService()47 MediaKeySessionService::~MediaKeySessionService()
48 {
49 DRM_INFO_LOG("~MediaKeySessionService 0x%{public}06" PRIXPTR " Instances destroy.", FAKE_POINTER(this));
50 }
51
CloseMediaKeySessionServiceByCallback()52 int32_t MediaKeySessionService::CloseMediaKeySessionServiceByCallback()
53 {
54 DRM_INFO_LOG("CloseMediaKeySessionServiceByCallback enter.");
55 {
56 std::lock_guard<std::recursive_mutex> lock(callbackMutex_);
57 sessionOperatorsCallback_ = nullptr;
58 }
59 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
60 int32_t currentPid = IPCSkeleton::GetCallingPid();
61 DRM_DEBUG_LOG("GetCallingPID: %{public}d", currentPid);
62 if (hdiMediaKeySession_ != nullptr) {
63 DRM_INFO_LOG("hdiMediaKeySession_ CloseHdiMediaKeySession");
64 hdiMediaKeySession_->Destroy();
65 hdiMediaKeySession_ = nullptr;
66 }
67
68 return DRM_INNER_ERR_OK;
69 }
70
Release()71 int32_t MediaKeySessionService::Release()
72 {
73 DRM_INFO_LOG("Release enter.");
74 std::lock_guard<std::recursive_mutex> lock(callbackMutex_);
75 int32_t currentPid = IPCSkeleton::GetCallingPid();
76 DRM_DEBUG_LOG("MediaKeySessionService GetCallingPID: %{public}d", currentPid);
77 if (sessionOperatorsCallback_ != nullptr) {
78 sessionOperatorsCallback_->CloseMediaKeySessionService(this);
79 }
80 return DRM_INNER_ERR_OK;
81 }
82
SetMediaKeySessionServiceOperatorsCallback(wptr<IMediaKeySessionServiceOperatorsCallback> callback)83 int32_t MediaKeySessionService::SetMediaKeySessionServiceOperatorsCallback(
84 wptr<IMediaKeySessionServiceOperatorsCallback> callback)
85 {
86 DRM_INFO_LOG("SetMediaKeySessionServiceOperatorsCallback enter.");
87 std::lock_guard<std::recursive_mutex> lock(callbackMutex_);
88 if (callback.promote() == nullptr) {
89 DRM_ERR_LOG("SetMediaKeySessionServiceOperatorsCallback callback is null");
90 return DRM_INNER_ERR_INVALID_VAL;
91 }
92 sessionOperatorsCallback_ = callback;
93 return DRM_INNER_ERR_OK;
94 }
95
GenerateMediaKeyRequest(const MediaKeyRequestInfo & licenseRequestInfo,MediaKeyRequest & licenseRequest)96 int32_t MediaKeySessionService::GenerateMediaKeyRequest(
97 const MediaKeyRequestInfo &licenseRequestInfo, MediaKeyRequest &licenseRequest)
98 {
99 DrmTrace trace("GenerateMediaKeyRequest");
100 DRM_INFO_LOG("GenerateMediaKeyRequest enter.");
101 int32_t ret = DRM_INNER_ERR_OK;
102 OHOS::HDI::Drm::V1_0::MediaKeyRequestInfo hdiMediaKeyRequestInfo;
103 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
104 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
105 "hdiMediaKeySession_ is nullptr!");
106
107 hdiMediaKeyRequestInfo.mediaKeyType = (OHOS::HDI::Drm::V1_0::MediaKeyType)licenseRequestInfo.mediaKeyType;
108 hdiMediaKeyRequestInfo.mimeType = licenseRequestInfo.mimeType;
109 hdiMediaKeyRequestInfo.initData.assign(licenseRequestInfo.initData.begin(), licenseRequestInfo.initData.end());
110 for (auto it = licenseRequestInfo.optionalData.begin();
111 it != licenseRequestInfo.optionalData.end(); ++it) {
112 hdiMediaKeyRequestInfo.optionalData.insert(std::make_pair(it->first, it->second));
113 }
114 OHOS::HDI::Drm::V1_0::MediaKeyRequest hdiMediaKeyRequest;
115 mediaKeyType_ = std::to_string(static_cast<int32_t>(licenseRequestInfo.mediaKeyType));
116 auto timeBefore = std::chrono::system_clock::now();
117 ret = hdiMediaKeySession_->GenerateMediaKeyRequest(hdiMediaKeyRequestInfo, hdiMediaKeyRequest);
118 generationDuration_ = CalculateTimeDiff(timeBefore, std::chrono::system_clock::now());
119 if (ret != DRM_INNER_ERR_OK) {
120 generationResult_ = "failed";
121 DRM_ERR_LOG("GenerateMediaKeyRequest failed.");
122 ReportFaultEvent(ret, "GenerateMediaKeyRequest failed", "");
123 return ret;
124 }
125 generationResult_ = "success";
126 licenseRequest.requestType = (RequestType)hdiMediaKeyRequest.requestType;
127 licenseRequest.mData.assign(hdiMediaKeyRequest.data.begin(), hdiMediaKeyRequest.data.end());
128 licenseRequest.mDefaultURL = hdiMediaKeyRequest.defaultUrl;
129 return ret;
130 }
131
ProcessMediaKeyResponse(std::vector<uint8_t> & licenseId,const std::vector<uint8_t> & licenseResponse)132 int32_t MediaKeySessionService::ProcessMediaKeyResponse(std::vector<uint8_t> &licenseId,
133 const std::vector<uint8_t> &licenseResponse)
134 {
135 DrmTrace trace("ProcessMediaKeyResponse");
136 DRM_INFO_LOG("ProcessMediaKeyResponse enter.");
137 int32_t ret = DRM_INNER_ERR_OK;
138 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
139 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
140 "hdiMediaKeySession_ is nullptr!");
141 auto timeBefore = std::chrono::system_clock::now();
142 ret = hdiMediaKeySession_->ProcessMediaKeyResponse(licenseResponse, licenseId);
143 uint32_t processDuration = CalculateTimeDiff(timeBefore, std::chrono::system_clock::now());
144 if (ret != DRM_INNER_ERR_OK) {
145 DRM_ERR_LOG("ProcessMediaKeyResponse failed.");
146 std::string responseString = std::string(reinterpret_cast<const char*>(licenseResponse.data()),
147 licenseResponse.size());
148 ReportFaultEvent(ret, "ProcessMediaKeyResponse failed", responseString);
149 return ret;
150 }
151 struct DownLoadInfo downLoadInfo = InitDownLoadInfo(generationDuration_, generationResult_, processDuration,
152 "success");
153 ReportLicenseBehaviorEvent(statisticsInfo_, mediaKeyType_, downLoadInfo);
154 return ret;
155 }
156
GenerateOfflineReleaseRequest(const std::vector<uint8_t> & licenseId,std::vector<uint8_t> & releaseRequest)157 int32_t MediaKeySessionService::GenerateOfflineReleaseRequest(const std::vector<uint8_t> &licenseId,
158 std::vector<uint8_t> &releaseRequest)
159 {
160 DRM_INFO_LOG("GenerateOfflineReleaseRequest enter.");
161 int32_t ret = DRM_INNER_ERR_OK;
162 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
163 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
164 "hdiMediaKeySession_ is nullptr!");
165 ret = hdiMediaKeySession_->GetOfflineReleaseRequest(licenseId, releaseRequest);
166 DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_INNER_ERR_OK, ret, "GenerateOfflineReleaseRequest failed.");
167 return ret;
168 }
169
ProcessOfflineReleaseResponse(const std::vector<uint8_t> & licenseId,const std::vector<uint8_t> & releaseResponse)170 int32_t MediaKeySessionService::ProcessOfflineReleaseResponse(const std::vector<uint8_t> &licenseId,
171 const std::vector<uint8_t> &releaseResponse)
172 {
173 DRM_INFO_LOG("ProcessOfflineReleaseResponse enter.");
174 int32_t ret = DRM_INNER_ERR_OK;
175 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
176 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
177 "hdiMediaKeySession_ is nullptr!");
178
179 ret = hdiMediaKeySession_->ProcessOfflineReleaseResponse(licenseId, releaseResponse);
180 DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_INNER_ERR_OK, ret, "ProcessOfflineReleaseResponse failed.");
181 return ret;
182 }
183
CheckMediaKeyStatus(std::map<std::string,std::string> & licenseStatus)184 int32_t MediaKeySessionService::CheckMediaKeyStatus(std::map<std::string, std::string> &licenseStatus)
185 {
186 DRM_INFO_LOG("CheckMediaKeyStatus enter.");
187 int32_t ret = DRM_INNER_ERR_OK;
188 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
189 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
190 "hdiMediaKeySession_ is nullptr!");
191 std::map<std::string, std::string> mp;
192 ret = hdiMediaKeySession_->CheckMediaKeyStatus(mp);
193 DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_INNER_ERR_OK, ret, "CheckMediaKeyStatus failed.");
194 for (auto m : mp) {
195 std::string name = m.first;
196 std::string status = m.second;
197 licenseStatus.insert(std::make_pair(name, status));
198 }
199 DRM_CHECK_AND_RETURN_RET_LOG(
200 licenseStatus.size() != 0, DRM_INNER_ERR_BASE, "CheckMediaKeyStatus licenseStatus is empty.");
201 return ret;
202 }
203
RestoreOfflineMediaKeys(const std::vector<uint8_t> & licenseId)204 int32_t MediaKeySessionService::RestoreOfflineMediaKeys(const std::vector<uint8_t> &licenseId)
205 {
206 DRM_INFO_LOG("RestoreOfflineMediaKeys enter.");
207 int32_t ret = DRM_INNER_ERR_OK;
208 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
209 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
210 "hdiMediaKeySession_ is nullptr!");
211 ret = hdiMediaKeySession_->RestoreOfflineMediaKeys(licenseId);
212 DRM_CHECK_AND_RETURN_RET_LOG(
213 ret == DRM_INNER_ERR_OK, ret, "RestoreOfflineMediaKeys failed.");
214 return ret;
215 }
216
ClearMediaKeys()217 int32_t MediaKeySessionService::ClearMediaKeys()
218 {
219 DRM_INFO_LOG("ClearMediaKeys enter.");
220 int32_t ret = DRM_INNER_ERR_OK;
221 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
222 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
223 "hdiMediaKeySession_ is nullptr!");
224 ret = hdiMediaKeySession_->ClearMediaKeys();
225 DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_INNER_ERR_OK, ret, "ClearMediaKeys failed.");
226 return ret;
227 }
228
GetContentProtectionLevel(ContentProtectionLevel & securityLevel)229 int32_t MediaKeySessionService::GetContentProtectionLevel(ContentProtectionLevel &securityLevel)
230 {
231 DRM_INFO_LOG("GetContentProtectionLevel enter.");
232 int32_t ret = DRM_INNER_ERR_OK;
233 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
234 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
235 "hdiMediaKeySession_ is nullptr!");
236 OHOS::HDI::Drm::V1_0::ContentProtectionLevel level;
237 ret = hdiMediaKeySession_->GetContentProtectionLevel(level);
238 DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_INNER_ERR_OK, ret, "GetContentProtectionLevel failed.");
239 securityLevel = (ContentProtectionLevel)level;
240 return ret;
241 }
242
GetMediaDecryptModule(sptr<IMediaDecryptModuleService> & decryptModule)243 int32_t MediaKeySessionService::GetMediaDecryptModule(sptr<IMediaDecryptModuleService> &decryptModule)
244 {
245 DrmTrace trace("GetMediaDecryptModule");
246 DRM_INFO_LOG("GetMediaDecryptModule enter.");
247 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
248 decryptModule = decryptModule_;
249 DRM_CHECK_AND_RETURN_RET_LOG(decryptModule_ == nullptr, DRM_INNER_ERR_OK, "decryptModule already exists.");
250 sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> hdiDecryptModule = nullptr;
251 DRM_CHECK_AND_RETURN_RET_LOG(
252 hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_INVALID_KEY_SESSION, "hdiMediaKeySession_ == nullptr");
253 int32_t retCode = DRM_INNER_ERR_OK;
254 retCode = hdiMediaKeySession_->GetMediaDecryptModule(hdiDecryptModule);
255 DRM_CHECK_AND_RETURN_RET_LOG(retCode == DRM_INNER_ERR_OK && hdiDecryptModule != nullptr,
256 DRM_INNER_ERR_BASE,
257 "hdiDecryptModule allocation failed.");
258 decryptModule_ = new (std::nothrow) MediaDecryptModuleService(hdiDecryptModule, statisticsInfo_);
259 DRM_CHECK_AND_RETURN_RET_LOG(
260 decryptModule_ != nullptr, DRM_INNER_ERR_NO_MEMORY, "New MediaDecryptModuleService allocation failed.");
261 decryptModule = decryptModule_;
262 return DRM_INNER_ERR_OK;
263 }
264
RequireSecureDecoderModule(const std::string & mimeType,bool & status)265 int32_t MediaKeySessionService::RequireSecureDecoderModule(const std::string &mimeType, bool &status)
266 {
267 DRM_INFO_LOG("RequireSecureDecoderModule enter.");
268
269 int32_t ret = DRM_INNER_ERR_OK;
270 (void)mimeType;
271 (void)status;
272 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
273 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr, DRM_INNER_ERR_SERVICE_FATAL_ERROR,
274 "hdiMediaKeySession_ is nullptr!");
275 ret = hdiMediaKeySession_->RequiresSecureDecoderModule(mimeType, status);
276 DRM_CHECK_AND_RETURN_RET_LOG(ret == DRM_INNER_ERR_OK, ret, "RequireSecureDecoderModule failed.");
277 return ret;
278 }
279
SetCallback(const sptr<IMediaKeySessionServiceCallback> & callback)280 int32_t MediaKeySessionService::SetCallback(const sptr<IMediaKeySessionServiceCallback> &callback)
281 {
282 DRM_INFO_LOG("SetCallback enter.");
283 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
284 DRM_CHECK_AND_RETURN_RET_LOG(callback != nullptr, DRM_INNER_ERR_BASE, "SetCallback nullptr failed.");
285 callback_ = callback;
286 DRM_CHECK_AND_RETURN_RET_LOG(hdiMediaKeySession_ != nullptr,
287 DRM_INNER_ERR_OPERATION_NOT_PERMITTED,
288 "SetCallback hdiMediaKeySession_ is nullptr , failed.");
289 return hdiMediaKeySession_->SetCallback(this);
290 }
291
SendEvent(OHOS::HDI::Drm::V1_0::EventType eventType,int32_t extra,const std::vector<uint8_t> & data)292 int32_t MediaKeySessionService::SendEvent(OHOS::HDI::Drm::V1_0::EventType eventType, int32_t extra,
293 const std::vector<uint8_t> &data)
294 {
295 DRM_INFO_LOG("SendEvent.");
296 DrmEventType event = static_cast<DrmEventType>(eventType);
297 DRM_CHECK_AND_RETURN_RET_LOG(
298 callback_ != nullptr, DRM_INNER_ERR_OPERATION_NOT_PERMITTED, "SendEvent callback not set");
299 return callback_->SendEvent(event, extra, data);
300 }
301
SendEventKeyChange(const std::map<std::vector<uint8_t>,OHOS::HDI::Drm::V1_0::MediaKeySessionKeyStatus> & keyStatus,bool hasNewGoodLicense)302 int32_t MediaKeySessionService::SendEventKeyChange(
303 const std::map<std::vector<uint8_t>, OHOS::HDI::Drm::V1_0::MediaKeySessionKeyStatus> &keyStatus,
304 bool hasNewGoodLicense)
305 {
306 DRM_INFO_LOG("SendEventKeyChange.");
307 std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> keyStatusMap;
308 for (auto item : keyStatus) {
309 keyStatusMap.insert({ item.first, static_cast<MediaKeySessionKeyStatus>(item.second) });
310 }
311 DRM_CHECK_AND_RETURN_RET_LOG(
312 callback_ != nullptr, DRM_INNER_ERR_OPERATION_NOT_PERMITTED, "SendEventKeyChange callback not set");
313 return callback_->SendEventKeyChanged(keyStatusMap, hasNewGoodLicense);
314 }
315
GetDecryptModuleDumpInfo()316 std::string MediaKeySessionService::GetDecryptModuleDumpInfo()
317 {
318 std::lock_guard<std::recursive_mutex> lock(sessionMutex_);
319 DRM_CHECK_AND_RETURN_RET_LOG(
320 decryptModule_ != nullptr, "", "get decrypt dump info: decrypt module is null");
321 return decryptModule_->GetDumpInfo();
322 }
323 } // DrmStandard
324 } // OHOS
325