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