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