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