diff options
Diffstat (limited to 'drm/libdrmframework/include/PlugInManager.h')
-rw-r--r-- | drm/libdrmframework/include/PlugInManager.h | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h new file mode 100644 index 0000000..9ad195f --- /dev/null +++ b/drm/libdrmframework/include/PlugInManager.h @@ -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__ */ + |