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 <memory>
17 #include <unistd.h>
18 #include <securec.h>
19 #include <algorithm>
20 #include "ashmem.h"
21 #include "system_ability_definition.h"
22 #include "mem_mgr_client.h"
23 #include "mem_mgr_proxy.h"
24 #include "drm_trace.h"
25 #include "drm_dfx_utils.h"
26 #include "drm_error_code.h"
27 #include "hitrace/tracechain.h"
28 #include "ipc_skeleton.h"
29 #include "media_decrypt_module_service.h"
30
31 namespace OHOS {
32 namespace DrmStandard {
33
34 const uint32_t TOP_THREE_SIZE = 3;
35 const uint32_t TOP_ONE = 0;
36 const uint32_t TOP_SEC = 1;
37 const uint32_t TOP_THD = 2;
38
MediaDecryptModuleService(sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> hdiMediaDecryptModule)39 MediaDecryptModuleService::MediaDecryptModuleService(
40 sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> hdiMediaDecryptModule)
41 {
42 DRM_INFO_LOG("MediaDecryptModuleService 0x%{public}06" PRIXPTR " Instances create.", FAKE_POINTER(this));
43 hdiMediaDecryptModule_ = hdiMediaDecryptModule;
44 instanceId_ = HiTraceChain::GetId().GetChainId();
45 }
46
MediaDecryptModuleService(sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> hdiMediaDecryptModule,StatisticsInfo statisticsInfo)47 MediaDecryptModuleService::MediaDecryptModuleService(
48 sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> hdiMediaDecryptModule,
49 StatisticsInfo statisticsInfo)
50 {
51 DRM_INFO_LOG("MediaDecryptModuleService 0x%{public}06" PRIXPTR " Instances create.", FAKE_POINTER(this));
52 std::lock_guard<std::recursive_mutex> lock(moduleLock_);
53 hdiMediaDecryptModule_ = hdiMediaDecryptModule;
54 statisticsInfo_ = statisticsInfo;
55 instanceId_ = HiTraceChain::GetId().GetChainId();
56 }
57
~MediaDecryptModuleService()58 MediaDecryptModuleService::~MediaDecryptModuleService()
59 {
60 DRM_INFO_LOG("~MediaDecryptModuleService 0x%{public}06" PRIXPTR " Instances destroy.", FAKE_POINTER(this));
61 std::lock_guard<std::recursive_mutex> lock(moduleLock_);
62 if (hdiMediaDecryptModule_ != nullptr) {
63 Release();
64 }
65 std::lock_guard<std::recursive_mutex> statisticsLock(statisticsMutex_);
66 ReportDecryptionStatisticsEvent(instanceId_, statisticsInfo_.bundleName, decryptStatistics_);
67 }
68
Release()69 int32_t MediaDecryptModuleService::Release()
70 {
71 DrmTrace trace("Release");
72 DRM_INFO_LOG("Release enter.");
73 int32_t errCode = DRM_OK;
74 std::lock_guard<std::recursive_mutex> lock(moduleLock_);
75 if (hdiMediaDecryptModule_ != nullptr) {
76 DRM_INFO_LOG("hdiMediaDecryptModule_ call Close");
77 hdiMediaDecryptModule_ = nullptr;
78 }
79 return errCode;
80 }
81
DecryptMediaData(bool secureDecodrtState,IMediaDecryptModuleService::CryptInfo & cryptInfo,IMediaDecryptModuleService::DrmBuffer & srcBuffer,IMediaDecryptModuleService::DrmBuffer & dstBuffer)82 int32_t MediaDecryptModuleService::DecryptMediaData(bool secureDecodrtState,
83 IMediaDecryptModuleService::CryptInfo &cryptInfo, IMediaDecryptModuleService::DrmBuffer &srcBuffer,
84 IMediaDecryptModuleService::DrmBuffer &dstBuffer)
85 {
86 DrmTrace trace("DecryptMediaData");
87 DRM_DEBUG_LOG("DecryptMediaData enter.");
88 int32_t ret = DRM_OK;
89 uint32_t bufLen = 0;
90 OHOS::HDI::Drm::V1_0::CryptoInfo cryptInfoTmp;
91 SetCryptInfo(cryptInfoTmp, cryptInfo, bufLen);
92 OHOS::HDI::Drm::V1_0::DrmBuffer drmSrcBuffer;
93 OHOS::HDI::Drm::V1_0::DrmBuffer drmDstBuffer;
94 memset_s(&drmSrcBuffer, sizeof(drmSrcBuffer), 0, sizeof(drmSrcBuffer));
95 memset_s(&drmDstBuffer, sizeof(drmDstBuffer), 0, sizeof(drmDstBuffer));
96 SetDrmBufferInfo(&drmSrcBuffer, &drmDstBuffer, srcBuffer, dstBuffer, bufLen);
97 auto timeBefore = std::chrono::system_clock::now();
98 std::lock_guard<std::recursive_mutex> lock(moduleLock_);
99 ret = hdiMediaDecryptModule_->DecryptMediaData(secureDecodrtState, cryptInfoTmp, drmSrcBuffer, drmDstBuffer);
100 uint32_t decryptDuration = CalculateTimeDiff(timeBefore, std::chrono::system_clock::now());
101 UpdateDecryptionStatistics(ret, bufLen, decryptDuration);
102 if (ret != DRM_OK) {
103 DRM_ERR_LOG("DecryptMediaData failed.");
104 ReportDecryptionFaultEvent(ret, "DecryptMediaData failed",
105 std::to_string(static_cast<int32_t>(cryptInfoTmp.type)),
106 CastToHexString(cryptInfoTmp.keyId), CastToHexString(cryptInfoTmp.iv));
107 }
108 (void)::close(srcBuffer.fd);
109 (void)::close(dstBuffer.fd);
110 return ret;
111 }
112
SetCryptInfo(OHOS::HDI::Drm::V1_0::CryptoInfo & cryptInfoTmp,IMediaDecryptModuleService::CryptInfo & cryptInfo,uint32_t & bufLen)113 void MediaDecryptModuleService::SetCryptInfo(OHOS::HDI::Drm::V1_0::CryptoInfo &cryptInfoTmp,
114 IMediaDecryptModuleService::CryptInfo &cryptInfo, uint32_t &bufLen)
115 {
116 cryptInfoTmp.type = (OHOS::HDI::Drm::V1_0::CryptoAlgorithmType)cryptInfo.type;
117 cryptInfoTmp.keyId.assign(cryptInfo.keyId.begin(), cryptInfo.keyId.end());
118 cryptInfoTmp.iv.assign(cryptInfo.iv.begin(), cryptInfo.iv.end());
119 cryptInfoTmp.pattern.encryptBlocks = cryptInfo.pattern.encryptBlocks;
120 cryptInfoTmp.pattern.skipBlocks = cryptInfo.pattern.skipBlocks;
121 cryptInfoTmp.subSamples.resize(cryptInfo.subSample.size());
122 for (size_t i = 0; i < cryptInfo.subSample.size(); i++) {
123 cryptInfoTmp.subSamples[i].clearHeaderLen = cryptInfo.subSample[i].clearHeaderLen;
124 bufLen += cryptInfoTmp.subSamples[i].clearHeaderLen;
125 cryptInfoTmp.subSamples[i].payLoadLen = cryptInfo.subSample[i].payLoadLen;
126 bufLen += cryptInfoTmp.subSamples[i].payLoadLen;
127 }
128 }
129
SetDrmBufferInfo(OHOS::HDI::Drm::V1_0::DrmBuffer * drmSrcBuffer,OHOS::HDI::Drm::V1_0::DrmBuffer * drmDstBuffer,IMediaDecryptModuleService::DrmBuffer & srcBuffer,IMediaDecryptModuleService::DrmBuffer & dstBuffer,uint32_t bufLen)130 void MediaDecryptModuleService::SetDrmBufferInfo(OHOS::HDI::Drm::V1_0::DrmBuffer* drmSrcBuffer,
131 OHOS::HDI::Drm::V1_0::DrmBuffer* drmDstBuffer, IMediaDecryptModuleService::DrmBuffer &srcBuffer,
132 IMediaDecryptModuleService::DrmBuffer &dstBuffer, uint32_t bufLen)
133 {
134 DRM_DEBUG_LOG("SetDrmBufferInfo enter");
135 drmSrcBuffer->bufferType = srcBuffer.bufferType;
136 drmSrcBuffer->fd = srcBuffer.fd;
137 drmSrcBuffer->bufferLen = bufLen;
138 drmSrcBuffer->allocLen = srcBuffer.allocLen;
139 drmSrcBuffer->filledLen = srcBuffer.filledLen;
140 drmSrcBuffer->offset = srcBuffer.offset;
141 drmSrcBuffer->fd = srcBuffer.fd;
142
143 drmDstBuffer->bufferType = dstBuffer.bufferType;
144 drmDstBuffer->fd = dstBuffer.fd;
145 drmDstBuffer->bufferLen = bufLen;
146 drmDstBuffer->allocLen = dstBuffer.allocLen;
147 drmDstBuffer->filledLen = dstBuffer.filledLen;
148 drmDstBuffer->offset = dstBuffer.offset;
149 drmDstBuffer->sharedMemType = dstBuffer.sharedMemType;
150 }
151
UpdateDecryptionStatistics(int32_t decryptionResult,uint32_t bufLen,uint32_t curDuration)152 void MediaDecryptModuleService::UpdateDecryptionStatistics(int32_t decryptionResult,
153 uint32_t bufLen, uint32_t curDuration)
154 {
155 std::lock_guard<std::recursive_mutex> statisticsLock(statisticsMutex_);
156 decryptStatistics_.topThree.push(curDuration);
157 if (decryptStatistics_.topThree.size() > TOP_THREE_SIZE) {
158 decryptStatistics_.topThree.pop();
159 }
160
161 decryptStatistics_.decryptMaxSize = std::max(decryptStatistics_.decryptMaxSize, bufLen);
162 decryptStatistics_.decryptMaxDuration = std::max(decryptStatistics_.decryptMaxDuration, curDuration);
163
164 if (decryptionResult != DRM_OK) {
165 decryptStatistics_.errorDecryptTimes++;
166 }
167 if (decryptStatistics_.decryptTimes == UINT32_MAX) {
168 decryptStatistics_.decryptTimes = 0;
169 decryptStatistics_.decryptSumSize = 0;
170 decryptStatistics_.decryptSumDuration = 0;
171 }
172 decryptStatistics_.decryptTimes++;
173 decryptStatistics_.decryptSumSize += bufLen;
174 decryptStatistics_.decryptSumDuration += curDuration;
175 }
176
GetTopThreeDecryptionDurations()177 const std::string MediaDecryptModuleService::GetTopThreeDecryptionDurations()
178 {
179 DRM_DEBUG_LOG("GetTopThreeDecryptionDurations");
180 std::vector<uint32_t> topThreeDurations(TOP_THREE_SIZE, 0);
181 std::lock_guard<std::recursive_mutex> statisticsLock(statisticsMutex_);
182 uint32_t currentTopThreeSize = decryptStatistics_.topThree.size();
183 for (uint32_t i = 0; i < currentTopThreeSize; i++) {
184 uint32_t tmp = decryptStatistics_.topThree.top();
185 decryptStatistics_.topThree.pop();
186 topThreeDurations[i] = tmp;
187 }
188 for (uint32_t i = 0; i < currentTopThreeSize; i++) {
189 decryptStatistics_.topThree.push(topThreeDurations[i]);
190 }
191 return std::to_string(topThreeDurations[TOP_ONE]) + " " +
192 std::to_string(topThreeDurations[TOP_SEC]) + " " +
193 std::to_string(topThreeDurations[TOP_THD]) + "\n";
194 }
195
GetDumpInfo()196 std::string MediaDecryptModuleService::GetDumpInfo()
197 {
198 DRM_DEBUG_LOG("GetDumpInfo");
199 std::lock_guard<std::recursive_mutex> statisticsLock(statisticsMutex_);
200 std::string dumpInfo = "Total Decryption Times: " + std::to_string(decryptStatistics_.decryptTimes) + "\n"
201 "Error Decryption Times: " + std::to_string(decryptStatistics_.errorDecryptTimes) + "\n"
202 "Top3 Decryption Duration: " + GetTopThreeDecryptionDurations();
203 return dumpInfo;
204 }
205
206 } // DrmStandard
207 } // OHOS