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