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