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