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