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