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