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 "DrmManager(Native)"
19 #include "utils/Log.h"
20 
21 #include <utils/String8.h>
22 #include <drm/DrmInfo.h>
23 #include <drm/DrmInfoEvent.h>
24 #include <drm/DrmRights.h>
25 #include <drm/DrmConstraints.h>
26 #include <drm/DrmMetadata.h>
27 #include <drm/DrmInfoStatus.h>
28 #include <drm/DrmInfoRequest.h>
29 #include <drm/DrmSupportInfo.h>
30 #include <drm/DrmConvertedStatus.h>
31 #include <IDrmEngine.h>
32 
33 #include "DrmManager.h"
34 #include "ReadWriteUtils.h"
35 
36 #define DECRYPT_FILE_ERROR -1
37 
38 using namespace android;
39 
40 const String8 DrmManager::EMPTY_STRING("");
41 
DrmManager()42 DrmManager::DrmManager() :
43     mDecryptSessionId(0),
44     mConvertId(0) {
45     srand(time(NULL));
46     memset(mUniqueIdArray, 0, sizeof(bool) * kMaxNumUniqueIds);
47 }
48 
~DrmManager()49 DrmManager::~DrmManager() {
50 
51 }
52 
addUniqueId(bool isNative)53 int DrmManager::addUniqueId(bool isNative) {
54     Mutex::Autolock _l(mLock);
55 
56     int uniqueId = -1;
57     int random = rand();
58 
59     for (size_t index = 0; index < kMaxNumUniqueIds; ++index) {
60         int temp = (random + index) % kMaxNumUniqueIds;
61         if (!mUniqueIdArray[temp]) {
62             uniqueId = temp;
63             mUniqueIdArray[uniqueId] = true;
64 
65             if (isNative) {
66                 // set a flag to differentiate DrmManagerClient
67                 // created from native side and java side
68                 uniqueId |= 0x1000;
69             }
70             break;
71         }
72     }
73 
74     // -1 indicates that no unique id can be allocated.
75     return uniqueId;
76 }
77 
removeUniqueId(int uniqueId)78 void DrmManager::removeUniqueId(int uniqueId) {
79     Mutex::Autolock _l(mLock);
80     if (uniqueId & 0x1000) {
81         // clear the flag for the native side.
82         uniqueId &= ~(0x1000);
83     }
84 
85     if (uniqueId >= 0 && uniqueId < kMaxNumUniqueIds) {
86         mUniqueIdArray[uniqueId] = false;
87     }
88 }
89 
loadPlugIns()90 status_t DrmManager::loadPlugIns() {
91 
92     String8 vendorPluginDirPath("/vendor/lib/drm");
93     loadPlugIns(vendorPluginDirPath);
94 
95     String8 pluginDirPath("/system/lib/drm");
96     loadPlugIns(pluginDirPath);
97     return DRM_NO_ERROR;
98 
99 }
100 
loadPlugIns(const String8 & plugInDirPath)101 status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
102     mPlugInManager.loadPlugIns(plugInDirPath);
103     Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
104     for (size_t i = 0; i < plugInPathList.size(); ++i) {
105         String8 plugInPath = plugInPathList[i];
106         DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
107         if (NULL != info) {
108             if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) {
109                 mSupportInfoToPlugInIdMap.add(*info, plugInPath);
110             }
111             delete info;
112         }
113     }
114     return DRM_NO_ERROR;
115 }
116 
unloadPlugIns()117 status_t DrmManager::unloadPlugIns() {
118     Mutex::Autolock _l(mLock);
119     mConvertSessionMap.clear();
120     mDecryptSessionMap.clear();
121     mPlugInManager.unloadPlugIns();
122     mSupportInfoToPlugInIdMap.clear();
123     return DRM_NO_ERROR;
124 }
125 
setDrmServiceListener(int uniqueId,const sp<IDrmServiceListener> & drmServiceListener)126 status_t DrmManager::setDrmServiceListener(
127             int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
128     Mutex::Autolock _l(mListenerLock);
129     if (NULL != drmServiceListener.get()) {
130         mServiceListeners.add(uniqueId, drmServiceListener);
131     } else {
132         mServiceListeners.removeItem(uniqueId);
133     }
134     return DRM_NO_ERROR;
135 }
136 
addClient(int uniqueId)137 void DrmManager::addClient(int uniqueId) {
138     Mutex::Autolock _l(mLock);
139     if (!mSupportInfoToPlugInIdMap.isEmpty()) {
140         Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
141         for (size_t index = 0; index < plugInIdList.size(); index++) {
142             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
143             rDrmEngine.initialize(uniqueId);
144             rDrmEngine.setOnInfoListener(uniqueId, this);
145         }
146     }
147 }
148 
removeClient(int uniqueId)149 void DrmManager::removeClient(int uniqueId) {
150     Mutex::Autolock _l(mLock);
151     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
152     for (size_t index = 0; index < plugInIdList.size(); index++) {
153         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
154         rDrmEngine.terminate(uniqueId);
155     }
156 }
157 
getConstraints(int uniqueId,const String8 * path,const int action)158 DrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
159     Mutex::Autolock _l(mLock);
160     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
161     if (EMPTY_STRING != plugInId) {
162         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
163         return rDrmEngine.getConstraints(uniqueId, path, action);
164     }
165     return NULL;
166 }
167 
getMetadata(int uniqueId,const String8 * path)168 DrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
169     Mutex::Autolock _l(mLock);
170     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
171     if (EMPTY_STRING != plugInId) {
172         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
173         return rDrmEngine.getMetadata(uniqueId, path);
174     }
175     return NULL;
176 }
177 
canHandle(int uniqueId,const String8 & path,const String8 & mimeType)178 bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
179     Mutex::Autolock _l(mLock);
180     const String8 plugInId = getSupportedPlugInId(mimeType);
181     bool result = (EMPTY_STRING != plugInId) ? true : false;
182 
183     if (0 < path.length()) {
184         if (result) {
185             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
186             result = rDrmEngine.canHandle(uniqueId, path);
187         } else {
188             String8 extension = path.getPathExtension();
189             if (String8("") != extension) {
190                 result = canHandle(uniqueId, path);
191             }
192         }
193     }
194     return result;
195 }
196 
processDrmInfo(int uniqueId,const DrmInfo * drmInfo)197 DrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
198     Mutex::Autolock _l(mLock);
199     const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
200     if (EMPTY_STRING != plugInId) {
201         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
202         return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
203     }
204     return NULL;
205 }
206 
canHandle(int uniqueId,const String8 & path)207 bool DrmManager::canHandle(int uniqueId, const String8& path) {
208     bool result = false;
209     Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
210 
211     for (size_t i = 0; i < plugInPathList.size(); ++i) {
212         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
213         result = rDrmEngine.canHandle(uniqueId, path);
214 
215         if (result) {
216             break;
217         }
218     }
219     return result;
220 }
221 
acquireDrmInfo(int uniqueId,const DrmInfoRequest * drmInfoRequest)222 DrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
223     Mutex::Autolock _l(mLock);
224     const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
225     if (EMPTY_STRING != plugInId) {
226         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
227         return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
228     }
229     return NULL;
230 }
231 
saveRights(int uniqueId,const DrmRights & drmRights,const String8 & rightsPath,const String8 & contentPath)232 status_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
233             const String8& rightsPath, const String8& contentPath) {
234     Mutex::Autolock _l(mLock);
235     const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
236     status_t result = DRM_ERROR_UNKNOWN;
237     if (EMPTY_STRING != plugInId) {
238         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
239         result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
240     }
241     return result;
242 }
243 
getOriginalMimeType(int uniqueId,const String8 & path,int fd)244 String8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
245     Mutex::Autolock _l(mLock);
246     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
247     if (EMPTY_STRING != plugInId) {
248         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
249         return rDrmEngine.getOriginalMimeType(uniqueId, path, fd);
250     }
251     return EMPTY_STRING;
252 }
253 
getDrmObjectType(int uniqueId,const String8 & path,const String8 & mimeType)254 int DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
255     Mutex::Autolock _l(mLock);
256     const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
257     if (EMPTY_STRING != plugInId) {
258         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
259         return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
260     }
261     return DrmObjectType::UNKNOWN;
262 }
263 
checkRightsStatus(int uniqueId,const String8 & path,int action)264 int DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
265     Mutex::Autolock _l(mLock);
266     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
267     if (EMPTY_STRING != plugInId) {
268         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
269         return rDrmEngine.checkRightsStatus(uniqueId, path, action);
270     }
271     return RightsStatus::RIGHTS_INVALID;
272 }
273 
consumeRights(int uniqueId,DecryptHandle * decryptHandle,int action,bool reserve)274 status_t DrmManager::consumeRights(
275     int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
276     status_t result = DRM_ERROR_UNKNOWN;
277     Mutex::Autolock _l(mDecryptLock);
278     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
279         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
280         result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
281     }
282     return result;
283 }
284 
setPlaybackStatus(int uniqueId,DecryptHandle * decryptHandle,int playbackStatus,int64_t position)285 status_t DrmManager::setPlaybackStatus(
286     int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
287     status_t result = DRM_ERROR_UNKNOWN;
288     Mutex::Autolock _l(mDecryptLock);
289     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
290         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
291         result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
292     }
293     return result;
294 }
295 
validateAction(int uniqueId,const String8 & path,int action,const ActionDescription & description)296 bool DrmManager::validateAction(
297     int uniqueId, const String8& path, int action, const ActionDescription& description) {
298     Mutex::Autolock _l(mLock);
299     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
300     if (EMPTY_STRING != plugInId) {
301         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
302         return rDrmEngine.validateAction(uniqueId, path, action, description);
303     }
304     return false;
305 }
306 
removeRights(int uniqueId,const String8 & path)307 status_t DrmManager::removeRights(int uniqueId, const String8& path) {
308     Mutex::Autolock _l(mLock);
309     const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
310     status_t result = DRM_ERROR_UNKNOWN;
311     if (EMPTY_STRING != plugInId) {
312         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
313         result = rDrmEngine.removeRights(uniqueId, path);
314     }
315     return result;
316 }
317 
removeAllRights(int uniqueId)318 status_t DrmManager::removeAllRights(int uniqueId) {
319     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
320     status_t result = DRM_ERROR_UNKNOWN;
321     for (size_t index = 0; index < plugInIdList.size(); index++) {
322         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
323         result = rDrmEngine.removeAllRights(uniqueId);
324         if (DRM_NO_ERROR != result) {
325             break;
326         }
327     }
328     return result;
329 }
330 
openConvertSession(int uniqueId,const String8 & mimeType)331 int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
332     Mutex::Autolock _l(mConvertLock);
333     int convertId = -1;
334 
335     const String8 plugInId = getSupportedPlugInId(mimeType);
336     if (EMPTY_STRING != plugInId) {
337         IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
338 
339         if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
340             ++mConvertId;
341             convertId = mConvertId;
342             mConvertSessionMap.add(convertId, &rDrmEngine);
343         }
344     }
345     return convertId;
346 }
347 
convertData(int uniqueId,int convertId,const DrmBuffer * inputData)348 DrmConvertedStatus* DrmManager::convertData(
349             int uniqueId, int convertId, const DrmBuffer* inputData) {
350     DrmConvertedStatus *drmConvertedStatus = NULL;
351 
352     Mutex::Autolock _l(mConvertLock);
353     if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
354         IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
355         drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
356     }
357     return drmConvertedStatus;
358 }
359 
closeConvertSession(int uniqueId,int convertId)360 DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
361     Mutex::Autolock _l(mConvertLock);
362     DrmConvertedStatus *drmConvertedStatus = NULL;
363 
364     if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
365         IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
366         drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
367         mConvertSessionMap.removeItem(convertId);
368     }
369     return drmConvertedStatus;
370 }
371 
getAllSupportInfo(int,int * length,DrmSupportInfo ** drmSupportInfoArray)372 status_t DrmManager::getAllSupportInfo(
373                     int /* uniqueId */, int* length, DrmSupportInfo** drmSupportInfoArray) {
374     Mutex::Autolock _l(mLock);
375     Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
376     int size = plugInPathList.size();
377     int validPlugins = 0;
378 
379     if (0 < size) {
380         Vector<DrmSupportInfo> drmSupportInfoList;
381 
382         for (int i = 0; i < size; ++i) {
383             String8 plugInPath = plugInPathList[i];
384             DrmSupportInfo* drmSupportInfo
385                 = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
386             if (NULL != drmSupportInfo) {
387                 drmSupportInfoList.add(*drmSupportInfo);
388                 delete drmSupportInfo; drmSupportInfo = NULL;
389             }
390         }
391 
392         validPlugins = drmSupportInfoList.size();
393         if (0 < validPlugins) {
394             *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
395             for (int i = 0; i < validPlugins; ++i) {
396                 (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
397             }
398         }
399     }
400     *length = validPlugins;
401     return DRM_NO_ERROR;
402 }
403 
openDecryptSession(int uniqueId,int fd,off64_t offset,off64_t length,const char * mime)404 DecryptHandle* DrmManager::openDecryptSession(
405         int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
406 
407     Mutex::Autolock _l(mDecryptLock);
408     status_t result = DRM_ERROR_CANNOT_HANDLE;
409     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
410 
411     DecryptHandle* handle = new DecryptHandle();
412     if (NULL != handle) {
413         handle->decryptId = mDecryptSessionId + 1;
414 
415         for (size_t index = 0; index < plugInIdList.size(); index++) {
416             String8 plugInId = plugInIdList.itemAt(index);
417             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
418             result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime);
419 
420             if (DRM_NO_ERROR == result) {
421                 ++mDecryptSessionId;
422                 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
423                 break;
424             }
425         }
426     }
427     if (DRM_NO_ERROR != result) {
428         delete handle; handle = NULL;
429     }
430     return handle;
431 }
432 
openDecryptSession(int uniqueId,const char * uri,const char * mime)433 DecryptHandle* DrmManager::openDecryptSession(
434         int uniqueId, const char* uri, const char* mime) {
435     Mutex::Autolock _l(mDecryptLock);
436     status_t result = DRM_ERROR_CANNOT_HANDLE;
437     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
438 
439     DecryptHandle* handle = new DecryptHandle();
440     if (NULL != handle) {
441         handle->decryptId = mDecryptSessionId + 1;
442 
443         for (size_t index = 0; index < plugInIdList.size(); index++) {
444             String8 plugInId = plugInIdList.itemAt(index);
445             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
446             result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime);
447 
448             if (DRM_NO_ERROR == result) {
449                 ++mDecryptSessionId;
450                 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
451                 break;
452             }
453         }
454     }
455     if (DRM_NO_ERROR != result) {
456         delete handle; handle = NULL;
457         ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
458     }
459     return handle;
460 }
461 
openDecryptSession(int uniqueId,const DrmBuffer & buf,const String8 & mimeType)462 DecryptHandle* DrmManager::openDecryptSession(
463         int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
464     Mutex::Autolock _l(mDecryptLock);
465     status_t result = DRM_ERROR_CANNOT_HANDLE;
466     Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
467 
468     DecryptHandle* handle = new DecryptHandle();
469     if (NULL != handle) {
470         handle->decryptId = mDecryptSessionId + 1;
471 
472         for (size_t index = 0; index < plugInIdList.size(); index++) {
473             String8 plugInId = plugInIdList.itemAt(index);
474             IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
475             result = rDrmEngine.openDecryptSession(uniqueId, handle, buf, mimeType);
476 
477             if (DRM_NO_ERROR == result) {
478                 ++mDecryptSessionId;
479                 mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
480                 break;
481             }
482         }
483     }
484     if (DRM_NO_ERROR != result) {
485         delete handle;
486         handle = NULL;
487         ALOGV("DrmManager::openDecryptSession: no capable plug-in found");
488     }
489     return handle;
490 }
491 
closeDecryptSession(int uniqueId,DecryptHandle * decryptHandle)492 status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
493     Mutex::Autolock _l(mDecryptLock);
494     status_t result = DRM_ERROR_UNKNOWN;
495     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
496         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
497         result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
498         if (DRM_NO_ERROR == result) {
499             mDecryptSessionMap.removeItem(decryptHandle->decryptId);
500         }
501     }
502     return result;
503 }
504 
initializeDecryptUnit(int uniqueId,DecryptHandle * decryptHandle,int decryptUnitId,const DrmBuffer * headerInfo)505 status_t DrmManager::initializeDecryptUnit(
506     int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
507     status_t result = DRM_ERROR_UNKNOWN;
508     Mutex::Autolock _l(mDecryptLock);
509     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
510         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
511         result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
512     }
513     return result;
514 }
515 
decrypt(int uniqueId,DecryptHandle * decryptHandle,int decryptUnitId,const DrmBuffer * encBuffer,DrmBuffer ** decBuffer,DrmBuffer * IV)516 status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
517             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
518     status_t result = DRM_ERROR_UNKNOWN;
519 
520     Mutex::Autolock _l(mDecryptLock);
521     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
522         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
523         result = drmEngine->decrypt(
524                 uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
525     }
526     return result;
527 }
528 
finalizeDecryptUnit(int uniqueId,DecryptHandle * decryptHandle,int decryptUnitId)529 status_t DrmManager::finalizeDecryptUnit(
530             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
531     status_t result = DRM_ERROR_UNKNOWN;
532     Mutex::Autolock _l(mDecryptLock);
533     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
534         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
535         result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
536     }
537     return result;
538 }
539 
pread(int uniqueId,DecryptHandle * decryptHandle,void * buffer,ssize_t numBytes,off64_t offset)540 ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
541             void* buffer, ssize_t numBytes, off64_t offset) {
542     ssize_t result = DECRYPT_FILE_ERROR;
543 
544     Mutex::Autolock _l(mDecryptLock);
545     if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
546         IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
547         result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
548     }
549     return result;
550 }
551 
getSupportedPlugInId(int uniqueId,const String8 & path,const String8 & mimeType)552 String8 DrmManager::getSupportedPlugInId(
553             int uniqueId, const String8& path, const String8& mimeType) {
554     String8 plugInId("");
555 
556     if (EMPTY_STRING != mimeType) {
557         plugInId = getSupportedPlugInId(mimeType);
558     } else {
559         plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
560     }
561     return plugInId;
562 }
563 
getSupportedPlugInId(const String8 & mimeType)564 String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
565     String8 plugInId("");
566 
567     if (EMPTY_STRING != mimeType) {
568         for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
569             const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
570 
571             if (drmSupportInfo.isSupportedMimeType(mimeType)) {
572                 plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
573                 break;
574             }
575         }
576     }
577     return plugInId;
578 }
579 
getSupportedPlugInIdFromPath(int uniqueId,const String8 & path)580 String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
581     String8 plugInId("");
582     const String8 fileSuffix = path.getPathExtension();
583 
584     for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
585         const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
586 
587         if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
588             String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
589             IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
590 
591             if (drmEngine.canHandle(uniqueId, path)) {
592                 plugInId = key;
593                 break;
594             }
595         }
596     }
597     return plugInId;
598 }
599 
onInfo(const DrmInfoEvent & event)600 void DrmManager::onInfo(const DrmInfoEvent& event) {
601     Mutex::Autolock _l(mListenerLock);
602     for (size_t index = 0; index < mServiceListeners.size(); index++) {
603         int uniqueId = mServiceListeners.keyAt(index);
604 
605         if (uniqueId == event.getUniqueId()) {
606             sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
607             serviceListener->notify(event);
608         }
609     }
610 }
611 
612