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