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