DrmManager.cpp revision ac2652c25f5d2a38709131f7731651bc5819fed5
195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/*
295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright (C) 2010 The Android Open Source Project
395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Licensed under the Apache License, Version 2.0 (the "License");
595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * you may not use this file except in compliance with the License.
695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * You may obtain a copy of the License at
795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *      http://www.apache.org/licenses/LICENSE-2.0
995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Unless required by applicable law or agreed to in writing, software
1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * distributed under the License is distributed on an "AS IS" BASIS,
1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * See the License for the specific language governing permissions and
1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * limitations under the License.
1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */
1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley//#define LOG_NDEBUG 0
1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define LOG_TAG "DrmManager(Native)"
1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "utils/Log.h"
2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <utils/String8.h>
2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmInfo.h>
2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmInfoEvent.h>
2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmRights.h>
2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmConstraints.h>
2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmMetadata.h>
2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmInfoStatus.h>
2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmInfoRequest.h>
2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmSupportInfo.h>
3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <drm/DrmConvertedStatus.h>
3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <IDrmEngine.h>
3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "DrmManager.h"
3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "ReadWriteUtils.h"
3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define DECRYPT_FILE_ERROR -1
3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyusing namespace android;
3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
4095c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyVector<int> DrmManager::mUniqueIdVector;
4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst String8 DrmManager::EMPTY_STRING("");
4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
4395c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmManager::DrmManager() :
4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mDecryptSessionId(0),
4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mConvertId(0) {
4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
4995c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmManager::~DrmManager() {
5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint DrmManager::addUniqueId(int uniqueId) {
5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (0 == uniqueId) {
5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        int temp = 0;
5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        bool foundUniqueId = false;
5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        srand(time(NULL));
5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        while (!foundUniqueId) {
6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            const int size = mUniqueIdVector.size();
6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            temp = rand() % 100;
6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            int index = 0;
6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            for (; index < size; ++index) {
6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                if (mUniqueIdVector.itemAt(index) == temp) {
6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                    foundUniqueId = false;
6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                    break;
6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                }
6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            }
7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            if (index == size) {
7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                foundUniqueId = true;
7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            }
7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        }
7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        uniqueId = temp;
7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mUniqueIdVector.push(uniqueId);
7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return uniqueId;
7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid DrmManager::removeUniqueId(int uniqueId) {
8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    for (unsigned int i = 0; i < mUniqueIdVector.size(); i++) {
8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        if (uniqueId == mUniqueIdVector.itemAt(i)) {
8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            mUniqueIdVector.removeAt(i);
8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            break;
8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        }
8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::loadPlugIns() {
9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    String8 pluginDirPath("/system/lib/drm/plugins/native");
9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return loadPlugIns(pluginDirPath);
9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (mSupportInfoToPlugInIdMap.isEmpty()) {
9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        mPlugInManager.loadPlugIns(plugInDirPath);
9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            String8 plugInPath = plugInPathList[i];
10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            if (NULL != info) {
10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley                mSupportInfoToPlugInIdMap.add(*info, plugInPath);
10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            }
10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        }
10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return DRM_NO_ERROR;
10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::unloadPlugIns() {
11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mConvertSessionMap.clear();
11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mDecryptSessionMap.clear();
11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mPlugInManager.unloadPlugIns();
11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mSupportInfoToPlugInIdMap.clear();
11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return DRM_NO_ERROR;
11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::setDrmServiceListener(
11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    Mutex::Autolock _l(mLock);
12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (NULL != drmServiceListener.get()) {
12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        mServiceListeners.add(uniqueId, drmServiceListener);
12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    } else {
12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        mServiceListeners.removeItem(uniqueId);
12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return DRM_NO_ERROR;
12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid DrmManager::addClient(int uniqueId) {
12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (!mSupportInfoToPlugInIdMap.isEmpty()) {
13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            rDrmEngine.initialize(uniqueId);
13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            rDrmEngine.setOnInfoListener(uniqueId, this);
13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        }
13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid DrmManager::removeClient(int uniqueId) {
14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        rDrmEngine.terminate(uniqueId);
14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
14795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmConstraints* DrmManager::getConstraints(int uniqueId, const String8* path, const int action) {
14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (EMPTY_STRING != plugInId) {
15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        return rDrmEngine.getConstraints(uniqueId, path, action);
15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return NULL;
15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
15695c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmMetadata* DrmManager::getMetadata(int uniqueId, const String8* path) {
15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, *path);
15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (EMPTY_STRING != plugInId) {
15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        return rDrmEngine.getMetadata(uniqueId, path);
16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return NULL;
16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mPlugInManager.loadPlugIn(absolutePath);
16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    rDrmEngine.initialize(uniqueId);
17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    rDrmEngine.setOnInfoListener(uniqueId, this);
17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    mSupportInfoToPlugInIdMap.add(*info, absolutePath);
17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return DRM_NO_ERROR;
17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleybool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInId(mimeType);
18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    bool result = (EMPTY_STRING != plugInId) ? true : false;
18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (0 < path.length()) {
18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        if (result) {
18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            result = rDrmEngine.canHandle(uniqueId, path);
18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        } else {
18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            result = canHandle(uniqueId, path);
18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        }
18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return result;
19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
19395c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmInfoStatus* DrmManager::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInId(drmInfo->getMimeType());
19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (EMPTY_STRING != plugInId) {
19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        return rDrmEngine.processDrmInfo(uniqueId, drmInfo);
19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return NULL;
20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleybool DrmManager::canHandle(int uniqueId, const String8& path) {
20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    bool result = false;
20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        result = rDrmEngine.canHandle(uniqueId, path);
20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        if (result) {
21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            break;
21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        }
21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return result;
21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
21795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDrmInfo* DrmManager::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInId(drmInfoRequest->getMimeType());
21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (EMPTY_STRING != plugInId) {
22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        return rDrmEngine.acquireDrmInfo(uniqueId, drmInfoRequest);
22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return NULL;
22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::saveRights(int uniqueId, const DrmRights& drmRights,
22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley            const String8& rightsPath, const String8& contentPath) {
22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInId(drmRights.getMimeType());
22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    status_t result = DRM_ERROR_UNKNOWN;
23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (EMPTY_STRING != plugInId) {
23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        result = rDrmEngine.saveRights(uniqueId, drmRights, rightsPath, contentPath);
23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return result;
23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
23795c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyString8 DrmManager::getOriginalMimeType(int uniqueId, const String8& path) {
23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (EMPTY_STRING != plugInId) {
24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        return rDrmEngine.getOriginalMimeType(uniqueId, path);
24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return EMPTY_STRING;
24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint DrmManager::getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType) {
24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInId(uniqueId, path, mimeType);
24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (EMPTY_STRING != plugInId) {
24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        return rDrmEngine.getDrmObjectType(uniqueId, path, mimeType);
25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return DrmObjectType::UNKNOWN;
25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint DrmManager::checkRightsStatus(int uniqueId, const String8& path, int action) {
25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (EMPTY_STRING != plugInId) {
25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        return rDrmEngine.checkRightsStatus(uniqueId, path, action);
26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return RightsStatus::RIGHTS_INVALID;
26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatus_t DrmManager::consumeRights(
265    int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
266    status_t result = DRM_ERROR_UNKNOWN;
267    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
268        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
269        result = drmEngine->consumeRights(uniqueId, decryptHandle, action, reserve);
270    }
271    return result;
272}
273
274status_t DrmManager::setPlaybackStatus(
275    int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
276    status_t result = DRM_ERROR_UNKNOWN;
277    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
278        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
279        result = drmEngine->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
280    }
281    return result;
282}
283
284bool DrmManager::validateAction(
285    int uniqueId, const String8& path, int action, const ActionDescription& description) {
286    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
287    if (EMPTY_STRING != plugInId) {
288        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
289        return rDrmEngine.validateAction(uniqueId, path, action, description);
290    }
291    return false;
292}
293
294status_t DrmManager::removeRights(int uniqueId, const String8& path) {
295    const String8 plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
296    status_t result = DRM_ERROR_UNKNOWN;
297    if (EMPTY_STRING != plugInId) {
298        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
299        result = rDrmEngine.removeRights(uniqueId, path);
300    }
301    return result;
302}
303
304status_t DrmManager::removeAllRights(int uniqueId) {
305    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
306    status_t result = DRM_ERROR_UNKNOWN;
307    for (unsigned int index = 0; index < plugInIdList.size(); index++) {
308        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
309        result = rDrmEngine.removeAllRights(uniqueId);
310        if (DRM_NO_ERROR != result) {
311            break;
312        }
313    }
314    return result;
315}
316
317int DrmManager::openConvertSession(int uniqueId, const String8& mimeType) {
318    int convertId = -1;
319
320    const String8 plugInId = getSupportedPlugInId(mimeType);
321    if (EMPTY_STRING != plugInId) {
322        IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
323
324        if (DRM_NO_ERROR == rDrmEngine.openConvertSession(uniqueId, mConvertId + 1)) {
325            Mutex::Autolock _l(mConvertLock);
326            ++mConvertId;
327            convertId = mConvertId;
328            mConvertSessionMap.add(convertId, &rDrmEngine);
329        }
330    }
331    return convertId;
332}
333
334DrmConvertedStatus* DrmManager::convertData(
335            int uniqueId, int convertId, const DrmBuffer* inputData) {
336    DrmConvertedStatus *drmConvertedStatus = NULL;
337
338    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
339        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
340        drmConvertedStatus = drmEngine->convertData(uniqueId, convertId, inputData);
341    }
342    return drmConvertedStatus;
343}
344
345DrmConvertedStatus* DrmManager::closeConvertSession(int uniqueId, int convertId) {
346    DrmConvertedStatus *drmConvertedStatus = NULL;
347
348    if (mConvertSessionMap.indexOfKey(convertId) != NAME_NOT_FOUND) {
349        IDrmEngine* drmEngine = mConvertSessionMap.valueFor(convertId);
350        drmConvertedStatus = drmEngine->closeConvertSession(uniqueId, convertId);
351        mConvertSessionMap.removeItem(convertId);
352    }
353    return drmConvertedStatus;
354}
355
356status_t DrmManager::getAllSupportInfo(
357                    int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
358    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
359    int size = plugInPathList.size();
360    int validPlugins = 0;
361
362    if (0 < size) {
363        Vector<DrmSupportInfo> drmSupportInfoList;
364
365        for (int i = 0; i < size; ++i) {
366            String8 plugInPath = plugInPathList[i];
367            DrmSupportInfo* drmSupportInfo
368                = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
369            if (NULL != drmSupportInfo) {
370                drmSupportInfoList.add(*drmSupportInfo);
371                delete drmSupportInfo; drmSupportInfo = NULL;
372            }
373        }
374
375        validPlugins = drmSupportInfoList.size();
376        if (0 < validPlugins) {
377            *drmSupportInfoArray = new DrmSupportInfo[validPlugins];
378            for (int i = 0; i < validPlugins; ++i) {
379                (*drmSupportInfoArray)[i] = drmSupportInfoList[i];
380            }
381        }
382    }
383    *length = validPlugins;
384    return DRM_NO_ERROR;
385}
386
387DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) {
388    Mutex::Autolock _l(mDecryptLock);
389    status_t result = DRM_ERROR_CANNOT_HANDLE;
390    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
391
392    DecryptHandle* handle = new DecryptHandle();
393    if (NULL != handle) {
394        handle->decryptId = mDecryptSessionId + 1;
395
396        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
397            String8 plugInId = plugInIdList.itemAt(index);
398            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
399            result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length);
400
401            if (DRM_NO_ERROR == result) {
402                ++mDecryptSessionId;
403                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
404                break;
405            }
406        }
407    }
408    if (DRM_NO_ERROR != result) {
409        delete handle; handle = NULL;
410    }
411    return handle;
412}
413
414DecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) {
415    Mutex::Autolock _l(mDecryptLock);
416    status_t result = DRM_ERROR_CANNOT_HANDLE;
417    Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
418
419    DecryptHandle* handle = new DecryptHandle();
420    if (NULL != handle) {
421        handle->decryptId = mDecryptSessionId + 1;
422
423        for (unsigned int index = 0; index < plugInIdList.size(); index++) {
424            String8 plugInId = plugInIdList.itemAt(index);
425            IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
426            result = rDrmEngine.openDecryptSession(uniqueId, handle, uri);
427
428            if (DRM_NO_ERROR == result) {
429                ++mDecryptSessionId;
430                mDecryptSessionMap.add(mDecryptSessionId, &rDrmEngine);
431                break;
432            }
433        }
434    }
435    if (DRM_NO_ERROR != result) {
436        delete handle; handle = NULL;
437        LOGE("DrmManager::openDecryptSession: no capable plug-in found");
438    }
439    return handle;
440}
441
442status_t DrmManager::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
443    Mutex::Autolock _l(mDecryptLock);
444    status_t result = DRM_ERROR_UNKNOWN;
445    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
446        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
447        result = drmEngine->closeDecryptSession(uniqueId, decryptHandle);
448        if (DRM_NO_ERROR == result) {
449            mDecryptSessionMap.removeItem(decryptHandle->decryptId);
450        }
451    }
452    return result;
453}
454
455status_t DrmManager::initializeDecryptUnit(
456    int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
457    status_t result = DRM_ERROR_UNKNOWN;
458    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
459        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
460        result = drmEngine->initializeDecryptUnit(uniqueId, decryptHandle, decryptUnitId, headerInfo);
461    }
462    return result;
463}
464
465status_t DrmManager::decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
466            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
467    status_t result = DRM_ERROR_UNKNOWN;
468    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
469        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
470        result = drmEngine->decrypt(
471                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
472    }
473    return result;
474}
475
476status_t DrmManager::finalizeDecryptUnit(
477            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
478    status_t result = DRM_ERROR_UNKNOWN;
479    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
480        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
481        result = drmEngine->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
482    }
483    return result;
484}
485
486ssize_t DrmManager::pread(int uniqueId, DecryptHandle* decryptHandle,
487            void* buffer, ssize_t numBytes, off64_t offset) {
488    ssize_t result = DECRYPT_FILE_ERROR;
489
490    if (mDecryptSessionMap.indexOfKey(decryptHandle->decryptId) != NAME_NOT_FOUND) {
491        IDrmEngine* drmEngine = mDecryptSessionMap.valueFor(decryptHandle->decryptId);
492        result = drmEngine->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
493    }
494    return result;
495}
496
497String8 DrmManager::getSupportedPlugInId(
498            int uniqueId, const String8& path, const String8& mimeType) {
499    String8 plugInId("");
500
501    if (EMPTY_STRING != mimeType) {
502        plugInId = getSupportedPlugInId(mimeType);
503    } else {
504        plugInId = getSupportedPlugInIdFromPath(uniqueId, path);
505    }
506    return plugInId;
507}
508
509String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
510    String8 plugInId("");
511
512    if (EMPTY_STRING != mimeType) {
513        for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
514            const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
515
516            if (drmSupportInfo.isSupportedMimeType(mimeType)) {
517                plugInId = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
518                break;
519            }
520        }
521    }
522    return plugInId;
523}
524
525String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& path) {
526    String8 plugInId("");
527    const String8 fileSuffix = path.getPathExtension();
528
529    for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
530        const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
531
532        if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
533            String8 key = mSupportInfoToPlugInIdMap.valueFor(drmSupportInfo);
534            IDrmEngine& drmEngine = mPlugInManager.getPlugIn(key);
535
536            if (drmEngine.canHandle(uniqueId, path)) {
537                plugInId = key;
538                break;
539            }
540        }
541    }
542    return plugInId;
543}
544
545void DrmManager::onInfo(const DrmInfoEvent& event) {
546    Mutex::Autolock _l(mLock);
547    for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
548        int uniqueId = mServiceListeners.keyAt(index);
549
550        if (uniqueId == event.getUniqueId()) {
551            sp<IDrmServiceListener> serviceListener = mServiceListeners.valueFor(uniqueId);
552            serviceListener->notify(event);
553        }
554    }
555}
556
557