• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     statisticsInfo_.targetVersion = 0;
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_INNER_ERR_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,const CryptInfo & cryptInfo,const DrmBuffer & srcBuffer,const DrmBuffer & dstBuffer)82 int32_t MediaDecryptModuleService::DecryptMediaData(bool secureDecodrtState,
83     const CryptInfo &cryptInfo, const DrmBuffer &srcBuffer, const 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,const CryptInfo & cryptInfo,uint32_t & bufLen)112 void MediaDecryptModuleService::SetCryptInfo(OHOS::HDI::Drm::V1_0::CryptoInfo &cryptInfoTmp,
113     const 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,const DrmBuffer & srcBuffer,const DrmBuffer & dstBuffer,uint32_t bufLen)129 void MediaDecryptModuleService::SetDrmBufferInfo(OHOS::HDI::Drm::V1_0::DrmBuffer* drmSrcBuffer,
130     OHOS::HDI::Drm::V1_0::DrmBuffer* drmDstBuffer, const DrmBuffer &srcBuffer,
131     const 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
207