xref: /aosp_15_r20/frameworks/av/drm/libdrmframework/plugins/passthru/src/DrmPassthruPlugIn.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "DrmPassthruPlugIn"
19 #include <utils/Log.h>
20 
21 #include <android-base/strings.h>
22 #include <drm/DrmRights.h>
23 #include <drm/DrmConstraints.h>
24 #include <drm/DrmMetadata.h>
25 #include <drm/DrmInfo.h>
26 #include <drm/DrmInfoEvent.h>
27 #include <drm/DrmInfoStatus.h>
28 #include <drm/DrmConvertedStatus.h>
29 #include <drm/DrmInfoRequest.h>
30 #include <drm/DrmSupportInfo.h>
31 #include <DrmPassthruPlugIn.h>
32 
33 #include <filesystem>
34 
35 using namespace android;
36 
37 
38 // This extern "C" is mandatory to be managed by TPlugInManager
create()39 extern "C" IDrmEngine* create() {
40     return new DrmPassthruPlugIn();
41 }
42 
43 // This extern "C" is mandatory to be managed by TPlugInManager
destroy(IDrmEngine * pPlugIn)44 extern "C" void destroy(IDrmEngine* pPlugIn) {
45     delete pPlugIn;
46     pPlugIn = NULL;
47 }
48 
DrmPassthruPlugIn()49 DrmPassthruPlugIn::DrmPassthruPlugIn()
50     : DrmEngineBase() {
51 
52 }
53 
~DrmPassthruPlugIn()54 DrmPassthruPlugIn::~DrmPassthruPlugIn() {
55 
56 }
57 
onGetMetadata(int,const String8 *)58 DrmMetadata* DrmPassthruPlugIn::onGetMetadata(int /*uniqueId*/, const String8* /*path*/) {
59     return NULL;
60 }
61 
onGetConstraints(int uniqueId,const String8 *,int)62 DrmConstraints* DrmPassthruPlugIn::onGetConstraints(
63         int uniqueId, const String8* /*path*/, int /*action*/) {
64     ALOGV("DrmPassthruPlugIn::onGetConstraints From Path: %d", uniqueId);
65     DrmConstraints* drmConstraints = new DrmConstraints();
66 
67     String8 value("dummy_available_time");
68     char* charValue = NULL;
69     charValue = new char[value.length() + 1];
70     strncpy(charValue, value.c_str(), value.length());
71     charValue[value.length()] = '\0';
72 
73     //Just add dummy available time for verification
74     drmConstraints->put(&(DrmConstraints::LICENSE_AVAILABLE_TIME), charValue);
75     delete[] charValue;
76     return drmConstraints;
77 }
78 
onProcessDrmInfo(int uniqueId,const DrmInfo * drmInfo)79 DrmInfoStatus* DrmPassthruPlugIn::onProcessDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
80     ALOGV("DrmPassthruPlugIn::onProcessDrmInfo - Enter : %d", uniqueId);
81     DrmInfoStatus* drmInfoStatus = NULL;
82     if (NULL != drmInfo) {
83         switch (drmInfo->getInfoType()) {
84         case DrmInfoRequest::TYPE_REGISTRATION_INFO: {
85             const DrmBuffer* emptyBuffer = new DrmBuffer();
86             drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
87                     DrmInfoRequest::TYPE_REGISTRATION_INFO, emptyBuffer, drmInfo->getMimeType());
88             break;
89         }
90         case DrmInfoRequest::TYPE_UNREGISTRATION_INFO: {
91             const DrmBuffer* emptyBuffer = new DrmBuffer();
92             drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
93                     DrmInfoRequest::TYPE_UNREGISTRATION_INFO, emptyBuffer, drmInfo->getMimeType());
94             break;
95         }
96         case DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO: {
97             String8 licenseString("dummy_license_string");
98             const int bufferSize = licenseString.size();
99             char* data = NULL;
100             data = new char[bufferSize];
101             memcpy(data, licenseString.c_str(), bufferSize);
102             const DrmBuffer* buffer = new DrmBuffer(data, bufferSize);
103             drmInfoStatus = new DrmInfoStatus(DrmInfoStatus::STATUS_OK,
104                     DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO, buffer, drmInfo->getMimeType());
105             break;
106         }
107         }
108     }
109     ALOGV("DrmPassthruPlugIn::onProcessDrmInfo - Exit");
110     return drmInfoStatus;
111 }
112 
onSetOnInfoListener(int uniqueId,const IDrmEngine::OnInfoListener *)113 status_t DrmPassthruPlugIn::onSetOnInfoListener(
114             int uniqueId, const IDrmEngine::OnInfoListener* /*infoListener*/) {
115     ALOGV("DrmPassthruPlugIn::onSetOnInfoListener : %d", uniqueId);
116     return DRM_NO_ERROR;
117 }
118 
onInitialize(int uniqueId)119 status_t DrmPassthruPlugIn::onInitialize(int uniqueId) {
120     ALOGV("DrmPassthruPlugIn::onInitialize : %d", uniqueId);
121     return DRM_NO_ERROR;
122 }
123 
onTerminate(int uniqueId)124 status_t DrmPassthruPlugIn::onTerminate(int uniqueId) {
125     ALOGV("DrmPassthruPlugIn::onTerminate : %d", uniqueId);
126     return DRM_NO_ERROR;
127 }
128 
onGetSupportInfo(int uniqueId)129 DrmSupportInfo* DrmPassthruPlugIn::onGetSupportInfo(int uniqueId) {
130     ALOGV("DrmPassthruPlugIn::onGetSupportInfo : %d", uniqueId);
131     DrmSupportInfo* drmSupportInfo = new DrmSupportInfo();
132     // Add mimetype's
133     drmSupportInfo->addMimeType(String8("application/vnd.passthru.drm"));
134     // Add File Suffixes
135     drmSupportInfo->addFileSuffix(String8(".passthru"));
136     // Add plug-in description
137     drmSupportInfo->setDescription(String8("Passthru plug-in"));
138     return drmSupportInfo;
139 }
140 
onSaveRights(int uniqueId,const DrmRights &,const String8 &,const String8 &)141 status_t DrmPassthruPlugIn::onSaveRights(int uniqueId, const DrmRights& /*drmRights*/,
142             const String8& /*rightsPath*/, const String8& /*contentPath*/) {
143     ALOGV("DrmPassthruPlugIn::onSaveRights : %d", uniqueId);
144     return DRM_NO_ERROR;
145 }
146 
onAcquireDrmInfo(int uniqueId,const DrmInfoRequest * drmInfoRequest)147 DrmInfo* DrmPassthruPlugIn::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
148     ALOGV("DrmPassthruPlugIn::onAcquireDrmInfo : %d", uniqueId);
149     DrmInfo* drmInfo = NULL;
150 
151     if (NULL != drmInfoRequest) {
152         String8 dataString("dummy_acquistion_string");
153         int length = dataString.length();
154         char* data = NULL;
155         data = new char[length];
156         memcpy(data, dataString.c_str(), length);
157         drmInfo = new DrmInfo(drmInfoRequest->getInfoType(),
158             DrmBuffer(data, length), drmInfoRequest->getMimeType());
159     }
160     return drmInfo;
161 }
162 
onCanHandle(int,const String8 & path)163 bool DrmPassthruPlugIn::onCanHandle(int /*uniqueId*/, const String8& path) {
164     ALOGV("DrmPassthruPlugIn::canHandle: %s ", path.c_str());
165     const auto extension = std::filesystem::path(path.c_str()).extension();
166     return base::EqualsIgnoreCase(extension.string(), ".passthru");
167 }
168 
onGetOriginalMimeType(int uniqueId,const String8 &,int)169 String8 DrmPassthruPlugIn::onGetOriginalMimeType(int uniqueId,
170             const String8& /*path*/, int /*fd*/) {
171     ALOGV("DrmPassthruPlugIn::onGetOriginalMimeType() : %d", uniqueId);
172     return String8("video/passthru");
173 }
174 
onGetDrmObjectType(int uniqueId,const String8 &,const String8 &)175 int DrmPassthruPlugIn::onGetDrmObjectType(
176             int uniqueId, const String8& /*path*/, const String8& /*mimeType*/) {
177     ALOGV("DrmPassthruPlugIn::onGetDrmObjectType() : %d", uniqueId);
178     return DrmObjectType::UNKNOWN;
179 }
180 
onCheckRightsStatus(int uniqueId,const String8 &,int)181 int DrmPassthruPlugIn::onCheckRightsStatus(int uniqueId, const String8& /*path*/, int /*action*/) {
182     ALOGV("DrmPassthruPlugIn::onCheckRightsStatus() : %d", uniqueId);
183     int rightsStatus = RightsStatus::RIGHTS_VALID;
184     return rightsStatus;
185 }
186 
onConsumeRights(int uniqueId,sp<DecryptHandle> &,int,bool)187 status_t DrmPassthruPlugIn::onConsumeRights(int uniqueId,
188             sp<DecryptHandle>& /*decryptHandle*/, int /*action*/, bool /*reserve*/) {
189     ALOGV("DrmPassthruPlugIn::onConsumeRights() : %d", uniqueId);
190     return DRM_NO_ERROR;
191 }
192 
onSetPlaybackStatus(int uniqueId,sp<DecryptHandle> &,int,int64_t)193 status_t DrmPassthruPlugIn::onSetPlaybackStatus(int uniqueId,
194             sp<DecryptHandle>& /*decryptHandle*/, int /*playbackStatus*/, int64_t /*position*/) {
195     ALOGV("DrmPassthruPlugIn::onSetPlaybackStatus() : %d", uniqueId);
196     return DRM_NO_ERROR;
197 }
198 
onValidateAction(int uniqueId,const String8 &,int,const ActionDescription &)199 bool DrmPassthruPlugIn::onValidateAction(int uniqueId,
200             const String8& /*path*/, int /*action*/, const ActionDescription& /*description*/) {
201     ALOGV("DrmPassthruPlugIn::onValidateAction() : %d", uniqueId);
202     return true;
203 }
204 
onRemoveRights(int uniqueId,const String8 &)205 status_t DrmPassthruPlugIn::onRemoveRights(int uniqueId, const String8& /*path*/) {
206     ALOGV("DrmPassthruPlugIn::onRemoveRights() : %d", uniqueId);
207     return DRM_NO_ERROR;
208 }
209 
onRemoveAllRights(int uniqueId)210 status_t DrmPassthruPlugIn::onRemoveAllRights(int uniqueId) {
211     ALOGV("DrmPassthruPlugIn::onRemoveAllRights() : %d", uniqueId);
212     return DRM_NO_ERROR;
213 }
214 
onOpenConvertSession(int uniqueId,int)215 status_t DrmPassthruPlugIn::onOpenConvertSession(int uniqueId, int /*convertId*/) {
216     ALOGV("DrmPassthruPlugIn::onOpenConvertSession() : %d", uniqueId);
217     return DRM_NO_ERROR;
218 }
219 
onConvertData(int uniqueId,int,const DrmBuffer * inputData)220 DrmConvertedStatus* DrmPassthruPlugIn::onConvertData(
221             int uniqueId, int /*convertId*/, const DrmBuffer* inputData) {
222     ALOGV("DrmPassthruPlugIn::onConvertData() : %d", uniqueId);
223     DrmBuffer* convertedData = NULL;
224 
225     if (NULL != inputData && 0 < inputData->length) {
226         int length = inputData->length;
227         char* data = NULL;
228         data = new char[length];
229         convertedData = new DrmBuffer(data, length);
230         memcpy(convertedData->data, inputData->data, length);
231     }
232     return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, convertedData, 0 /*offset*/);
233 }
234 
onCloseConvertSession(int uniqueId,int)235 DrmConvertedStatus* DrmPassthruPlugIn::onCloseConvertSession(int uniqueId, int /*convertId*/) {
236     ALOGV("DrmPassthruPlugIn::onCloseConvertSession() : %d", uniqueId);
237     return new DrmConvertedStatus(DrmConvertedStatus::STATUS_OK, NULL, 0 /*offset*/);
238 }
239 
onOpenDecryptSession(int uniqueId,sp<DecryptHandle> & decryptHandle,int,off64_t,off64_t)240 status_t DrmPassthruPlugIn::onOpenDecryptSession(
241             int uniqueId, sp<DecryptHandle>& decryptHandle, int /*fd*/, off64_t /*offset*/,
242             off64_t /*length*/) {
243     ALOGV("DrmPassthruPlugIn::onOpenDecryptSession() : %d", uniqueId);
244 
245 #ifdef ENABLE_PASSTHRU_DECRYPTION
246     decryptHandle->mimeType = String8("video/passthru");
247     decryptHandle->decryptApiType = DecryptApiType::ELEMENTARY_STREAM_BASED;
248     decryptHandle->status = DRM_NO_ERROR;
249     decryptHandle->decryptInfo = NULL;
250     return DRM_NO_ERROR;
251 #else
252     (void)(decryptHandle.get()); // unused
253 #endif
254 
255     return DRM_ERROR_CANNOT_HANDLE;
256 }
257 
onOpenDecryptSession(int,sp<DecryptHandle> &,const char *)258 status_t DrmPassthruPlugIn::onOpenDecryptSession(
259             int /*uniqueId*/, sp<DecryptHandle>& /*decryptHandle*/, const char* /*uri*/) {
260     return DRM_ERROR_CANNOT_HANDLE;
261 }
262 
onCloseDecryptSession(int uniqueId,sp<DecryptHandle> & decryptHandle)263 status_t DrmPassthruPlugIn::onCloseDecryptSession(int uniqueId, sp<DecryptHandle>& decryptHandle) {
264     ALOGV("DrmPassthruPlugIn::onCloseDecryptSession() : %d", uniqueId);
265     if (NULL != decryptHandle.get()) {
266         if (NULL != decryptHandle->decryptInfo) {
267             delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
268         }
269         decryptHandle.clear();
270     }
271     return DRM_NO_ERROR;
272 }
273 
onInitializeDecryptUnit(int uniqueId,sp<DecryptHandle> &,int,const DrmBuffer *)274 status_t DrmPassthruPlugIn::onInitializeDecryptUnit(int uniqueId,
275         sp<DecryptHandle>& /*decryptHandle*/,
276         int /*decryptUnitId*/, const DrmBuffer* /*headerInfo*/) {
277     ALOGV("DrmPassthruPlugIn::onInitializeDecryptUnit() : %d", uniqueId);
278     return DRM_NO_ERROR;
279 }
280 
onDecrypt(int uniqueId,sp<DecryptHandle> &,int,const DrmBuffer * encBuffer,DrmBuffer ** decBuffer,DrmBuffer *)281 status_t DrmPassthruPlugIn::onDecrypt(int uniqueId, sp<DecryptHandle>& /*decryptHandle*/,
282         int /*decryptUnitId*/, const DrmBuffer* encBuffer, DrmBuffer** decBuffer,
283         DrmBuffer* /*IV*/) {
284     ALOGV("DrmPassthruPlugIn::onDecrypt() : %d", uniqueId);
285     /**
286      * As a workaround implementation passthru would copy the given
287      * encrypted buffer as it is to decrypted buffer. Note, decBuffer
288      * memory has to be allocated by the caller.
289      */
290     if (NULL != (*decBuffer) && 0 < (*decBuffer)->length) {
291         if ((*decBuffer)->length >= encBuffer->length) {
292             memcpy((*decBuffer)->data, encBuffer->data, encBuffer->length);
293             (*decBuffer)->length = encBuffer->length;
294         } else {
295             ALOGE("decBuffer size (%d) too small to hold %d bytes",
296                 (*decBuffer)->length, encBuffer->length);
297             return DRM_ERROR_UNKNOWN;
298         }
299     }
300     return DRM_NO_ERROR;
301 }
302 
onFinalizeDecryptUnit(int uniqueId,sp<DecryptHandle> &,int)303 status_t DrmPassthruPlugIn::onFinalizeDecryptUnit(
304             int uniqueId, sp<DecryptHandle>& /*decryptHandle*/, int /*decryptUnitId*/) {
305     ALOGV("DrmPassthruPlugIn::onFinalizeDecryptUnit() : %d", uniqueId);
306     return DRM_NO_ERROR;
307 }
308 
onPread(int uniqueId,sp<DecryptHandle> &,void *,ssize_t,off64_t)309 ssize_t DrmPassthruPlugIn::onPread(int uniqueId, sp<DecryptHandle>& /*decryptHandle*/,
310             void* /*buffer*/, ssize_t /*numBytes*/, off64_t /*offset*/) {
311     ALOGV("DrmPassthruPlugIn::onPread() : %d", uniqueId);
312     return 0;
313 }
314 
315