Initial contribution from Sony Corporation.
Add DRM Framework to support DRM content playback
together with StageFright.
- DRM Framework code is added
- include/drm
- drm
- api/current.xml is updated to include DRM Framework Java APIs
- cmds/servicemanager/service_manager.c is modified
to add drmManager and drmIOService.
Change-Id: I6d7bc9c7067362b500e530988a9ce241761866fb
This commit is contained in:
273
drm/libdrmframework/include/PlugInManager.h
Normal file
273
drm/libdrmframework/include/PlugInManager.h
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __PLUGIN_MANAGER_H__
|
||||
#define __PLUGIN_MANAGER_H__
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
const char* const PLUGIN_MANAGER_CREATE = "create";
|
||||
const char* const PLUGIN_MANAGER_DESTROY = "destroy";
|
||||
const char* const PLUGIN_EXTENSION = ".so";
|
||||
|
||||
/**
|
||||
* This is the template class for Plugin manager.
|
||||
*
|
||||
* The DrmManager uses this class to handle the plugins.
|
||||
*
|
||||
*/
|
||||
template<typename Type>
|
||||
class TPlugInManager {
|
||||
private:
|
||||
typedef void* HANDLE;
|
||||
typedef Type* create_t(void);
|
||||
typedef void destroy_t(Type*);
|
||||
typedef create_t* FPCREATE;
|
||||
typedef destroy_t* FPDESTORY;
|
||||
|
||||
typedef struct _PlugInContainer {
|
||||
String8 sPath;
|
||||
HANDLE hHandle;
|
||||
FPCREATE fpCreate;
|
||||
FPDESTORY fpDestory;
|
||||
Type* pInstance;
|
||||
|
||||
_PlugInContainer():
|
||||
sPath("")
|
||||
,hHandle(NULL)
|
||||
,fpCreate(NULL)
|
||||
,fpDestory(NULL)
|
||||
,pInstance(NULL)
|
||||
{}
|
||||
} PlugInContainer;
|
||||
|
||||
typedef KeyedVector<String8, PlugInContainer*> PlugInMap;
|
||||
PlugInMap m_plugInMap;
|
||||
|
||||
typedef Vector<String8> PlugInIdList;
|
||||
PlugInIdList m_plugInIdList;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Load all the plug-ins in the specified directory
|
||||
*
|
||||
* @param[in] rsPlugInDirPath
|
||||
* Directory path which plug-ins (dynamic library) are stored
|
||||
* @note Plug-ins should be implemented according to the specification
|
||||
*/
|
||||
void loadPlugIns(const String8& rsPlugInDirPath) {
|
||||
Vector<String8> plugInFileList = getPlugInPathList(rsPlugInDirPath);
|
||||
|
||||
if (!plugInFileList.isEmpty()) {
|
||||
for (unsigned int i = 0; i < plugInFileList.size(); ++i) {
|
||||
loadPlugIn(plugInFileList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload all the plug-ins
|
||||
*
|
||||
*/
|
||||
void unloadPlugIns() {
|
||||
for (unsigned int i = 0; i < m_plugInIdList.size(); ++i) {
|
||||
unloadPlugIn(m_plugInIdList[i]);
|
||||
}
|
||||
m_plugInIdList.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the IDs of available plug-ins
|
||||
*
|
||||
* @return[in] plugInIdList
|
||||
* String type Vector in which all plug-in IDs are stored
|
||||
*/
|
||||
Vector<String8> getPlugInIdList() const {
|
||||
return m_plugInIdList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a plug-in reference of specified ID
|
||||
*
|
||||
* @param[in] rsPlugInId
|
||||
* Plug-in ID to be used
|
||||
* @return plugIn
|
||||
* Reference of specified plug-in instance
|
||||
*/
|
||||
Type& getPlugIn(const String8& rsPlugInId) {
|
||||
if (!contains(rsPlugInId)) {
|
||||
// This error case never happens
|
||||
}
|
||||
return *(m_plugInMap.valueFor(rsPlugInId)->pInstance);
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Load a plug-in stored in the specified path
|
||||
*
|
||||
* @param[in] rsPlugInPath
|
||||
* Plug-in (dynamic library) file path
|
||||
* @note Plug-in should be implemented according to the specification
|
||||
*/
|
||||
void loadPlugIn(const String8& rsPlugInPath) {
|
||||
if (contains(rsPlugInPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlugInContainer* pPlugInContainer = new PlugInContainer();
|
||||
|
||||
pPlugInContainer->hHandle = dlopen(rsPlugInPath.string(), RTLD_LAZY);
|
||||
|
||||
if (NULL == pPlugInContainer->hHandle) {
|
||||
delete pPlugInContainer;
|
||||
pPlugInContainer = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
pPlugInContainer->sPath = rsPlugInPath;
|
||||
pPlugInContainer->fpCreate
|
||||
= (FPCREATE)dlsym(pPlugInContainer->hHandle, PLUGIN_MANAGER_CREATE);
|
||||
pPlugInContainer->fpDestory
|
||||
= (FPDESTORY)dlsym(pPlugInContainer->hHandle, PLUGIN_MANAGER_DESTROY);
|
||||
|
||||
if (NULL != pPlugInContainer->fpCreate && NULL != pPlugInContainer->fpDestory) {
|
||||
pPlugInContainer->pInstance = (Type*)pPlugInContainer->fpCreate();
|
||||
m_plugInIdList.add(rsPlugInPath);
|
||||
m_plugInMap.add(rsPlugInPath, pPlugInContainer);
|
||||
} else {
|
||||
dlclose(pPlugInContainer->hHandle);
|
||||
delete pPlugInContainer;
|
||||
pPlugInContainer = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload a plug-in stored in the specified path
|
||||
*
|
||||
* @param[in] rsPlugInPath
|
||||
* Plug-in (dynamic library) file path
|
||||
*/
|
||||
void unloadPlugIn(const String8& rsPlugInPath) {
|
||||
if (!contains(rsPlugInPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PlugInContainer* pPlugInContainer = m_plugInMap.valueFor(rsPlugInPath);
|
||||
pPlugInContainer->fpDestory(pPlugInContainer->pInstance);
|
||||
dlclose(pPlugInContainer->hHandle);
|
||||
|
||||
m_plugInMap.removeItem(rsPlugInPath);
|
||||
delete pPlugInContainer;
|
||||
pPlugInContainer = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* True if TPlugInManager contains rsPlugInId
|
||||
*/
|
||||
bool contains(const String8& rsPlugInId) {
|
||||
return m_plugInMap.indexOfKey(rsPlugInId) != NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return file path list of plug-ins stored in the specified directory
|
||||
*
|
||||
* @param[in] rsDirPath
|
||||
* Directory path in which plug-ins are stored
|
||||
* @return plugInFileList
|
||||
* String type Vector in which file path of plug-ins are stored
|
||||
*/
|
||||
Vector<String8> getPlugInPathList(const String8& rsDirPath) {
|
||||
Vector<String8> fileList;
|
||||
DIR* pDir = opendir(rsDirPath.string());
|
||||
struct dirent* pEntry = new dirent();
|
||||
|
||||
while (NULL != pDir && NULL != (pEntry = readdir(pDir))) {
|
||||
if (!isPlugIn(pEntry)) {
|
||||
continue;
|
||||
}
|
||||
String8 plugInPath;
|
||||
plugInPath += rsDirPath;
|
||||
plugInPath += "/";
|
||||
plugInPath += pEntry->d_name;
|
||||
|
||||
fileList.add(plugInPath);
|
||||
}
|
||||
|
||||
if (NULL != pDir) {
|
||||
closedir(pDir);
|
||||
}
|
||||
delete pEntry;
|
||||
pEntry = NULL;
|
||||
|
||||
return fileList;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the input name denotes plug-in
|
||||
*/
|
||||
bool isPlugIn(const struct dirent* pEntry) const {
|
||||
String8 sName(pEntry->d_name);
|
||||
int extentionPos = sName.size() - String8(PLUGIN_EXTENSION).size();
|
||||
if (extentionPos < 0) {
|
||||
return false;
|
||||
}
|
||||
return extentionPos == (int)sName.find(PLUGIN_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the input entry is "." or ".."
|
||||
*/
|
||||
bool isDotOrDDot(const struct dirent* pEntry) const {
|
||||
String8 sName(pEntry->d_name);
|
||||
return "." == sName || ".." == sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if input entry is directory
|
||||
*/
|
||||
bool isDirectory(const struct dirent* pEntry) const {
|
||||
return DT_DIR == pEntry->d_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if input entry is regular file
|
||||
*/
|
||||
bool isRegularFile(const struct dirent* pEntry) const {
|
||||
return DT_REG == pEntry->d_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if input entry is link
|
||||
*/
|
||||
bool isLink(const struct dirent* pEntry) const {
|
||||
return DT_LNK == pEntry->d_type;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif /* __PLUGIN_MANAGER_H__ */
|
||||
|
||||
Reference in New Issue
Block a user