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