added layermanager plugin mechanism
authorblacky <blacky@kiwi.(none)>
Tue, 19 Jul 2011 20:36:54 +0000 (22:36 +0200)
committerblacky <blacky@kiwi.(none)>
Tue, 19 Jul 2011 20:36:54 +0000 (22:36 +0200)
AudioManagerDaemon/AudioManagerCore.cpp
AudioManagerDaemon/AudioManagerCore.h
AudioManagerDaemon/CMakeLists.txt
AudioManagerDaemon/HookEngine.cpp
AudioManagerDaemon/PluginHandler.cpp [deleted file]
AudioManagerDaemon/PluginHandler.h [deleted file]
PluginHookStandard/CMakeLists.txt
PluginHookStandard/StandardHook.cpp
PluginHookStandard/StandardHook.h

index 2db4b60..8d1f867 100644 (file)
  *
  */
 
+
 #include "AudioManagerCore.h"
+#include <dirent.h>
+#include <dlfcn.h>
+#include <libgen.h>
 
 Task::Task() {
 }
@@ -626,3 +630,40 @@ void AudioManagerCore::addQueue(Queue* queue) {
        m_queueList.push_back(queue);
 }
 
+std::list<std::string> AudioManagerCore::getSharedLibrariesFromDirectory(std::string dirName) {
+
+       std::list<std::string> fileList;
+       // open directory
+    DIR *directory = opendir(dirName.c_str());
+    if (!directory)
+    {
+       DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Error opening directory "),DLT_STRING(dirName.c_str()));
+        return fileList;
+    }
+
+    // iterate content of directory
+    struct dirent *itemInDirectory = 0;
+    while ((itemInDirectory = readdir(directory)))
+    {
+        unsigned char entryType = itemInDirectory->d_type;
+        std::string entryName = itemInDirectory->d_name;
+
+        bool regularFile = (entryType == DT_REG);
+        bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
+
+        if (regularFile && sharedLibExtension)
+        {
+               DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("PluginSearch adding file "),DLT_STRING(entryName.c_str()));
+            fileList.push_back(dirName + "/" + entryName);
+        }
+        else
+        {
+               DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("PluginSearch ignoring file "),DLT_STRING(entryName.c_str()));
+        }
+    }
+
+    closedir(directory);
+    return fileList;
+}
+
+
index 9342ef2..5647a44 100644 (file)
@@ -610,6 +610,9 @@ public:
        void signal_numberOfSinksChanged();
        void signal_numberOfSourcesChanged();
 
+       std::list<std::string> getSharedLibrariesFromDirectory(std::string dirName);
+       template<class T>T* getCreateFunction(std::string libname);
+
 private:
        DataBaseHandler* m_databaseHandler; //!< pointer to the DataBasehandler Class
        Router* m_router; //!< pointer to the Router Class
index eb96741..4595356 100644 (file)
@@ -42,7 +42,6 @@ SET(AUDIOMAN_SRCS_CXX
     main.cpp
     DBusCommandInterface.cpp
     HookEngine.cpp
-    PluginHandler.cpp
 )
 
 INCLUDE_DIRECTORIES(
index 2f2eaa6..90e52b8 100644 (file)
 
 #include "HookEngine.h"
 
+/**
+ * this path needs to be adjusted to whatever is suitable on the system
+ */
+const char* hookPluginDirectories[] = { "/home/blacky/new_workspace/AudioManager/build/plugins"};
+uint hookPluginDirectoriesCount = sizeof(hookPluginDirectories) / sizeof(hookPluginDirectories[0]);
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <libgen.h>
+#include <unistd.h>
+
+template<class T>T* getCreateFunction(std::string libname) {
+
+       // cut off directories
+       char* fileWithPath = const_cast<char*>(libname.c_str());
+       std::string libFileName = basename(fileWithPath);
+
+       // cut off "lib" in front and cut off .so end"
+       std::string createFunctionName = libFileName.substr(3, libFileName.length() - 6) + "Factory";
+       DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Lib entry point name "),DLT_STRING(createFunctionName.c_str()));
+
+       // open library#include <unistd.h>
+       void *libraryHandle;
+       dlerror(); // Clear any existing error
+       libraryHandle = dlopen(libname.c_str(), RTLD_NOW /*LAZY*/);
+       const char* dlopen_error = dlerror();
+       if (!libraryHandle || dlopen_error)
+       {
+               DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("dlopen failed"),DLT_STRING(dlopen_error));
+               return 0;
+       }
+
+       // get entry point from shared lib
+       dlerror(); // Clear any existing error
+       DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("loading external function with name"),DLT_STRING(createFunctionName.c_str()));
+
+       union
+       {
+               void* voidPointer;
+               T* typedPointer;
+       } functionPointer;
+
+       // Note: direct cast is not allowed by ISO C++. e.g.
+       // T* createFunction = reinterpret_cast<T*>(dlsym(libraryHandle, createFunctionName.c_str()));
+       // compiler warning: "forbids casting between pointer-to-function and pointer-to-object"
+
+       functionPointer.voidPointer = dlsym(libraryHandle, createFunctionName.c_str());
+       T* createFunction = functionPointer.typedPointer;
+
+       const char* dlsym_error = dlerror();
+       if (!createFunction || dlsym_error)
+       {
+               DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Failed to load shared lib entry point"),DLT_STRING(dlsym_error));
+       }
+
+       return createFunction;
+}
+
+
 BaseHook::BaseHook() {
 }
 
@@ -329,21 +388,49 @@ void HookHandler::registerAudioManagerCore(AudioManagerCore* core) {
 }
 
 void HookHandler::loadHookPlugins() {
-       BaseHook *b = NULL;
-//     foreach(QObject * plugin, QPluginLoader::staticInstances())
-//     {
-//             HookPluginFactory* HookPluginFactory_ = qobject_cast<HookPluginFactory *>(plugin);
-//             if (HookPluginFactory_) {
-//                     b = HookPluginFactory_->returnInstance();
-//                     b->registerHookEngine(this);
-//                     b->registerAudioManagerCore(m_core);
-//                     b->InitHook();
-//                     char pName[40];
-//                     if (b->returnPluginName(pName) == GEN_OK) {
-//                             DLT_LOG( AudioManager, DLT_LOG_INFO, DLT_STRING("Registered Hook Plugin:"), DLT_STRING(pName));
-//                             m_listofPlugins.append(b);
-//                     }
-//             }
-//     }
+
+       std::list<std::string> sharedLibraryNameList;
+
+    // search communicator plugins in configured directories
+    for (uint dirIndex = 0; dirIndex < hookPluginDirectoriesCount; ++dirIndex) {
+        const char* directoryName = hookPluginDirectories[dirIndex];
+        DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Searching for HookPlugins in"),DLT_STRING(directoryName));
+        std::list<std::string> newList=m_core->getSharedLibrariesFromDirectory(directoryName);
+        sharedLibraryNameList.insert(sharedLibraryNameList.end(),newList.begin(),newList.end());
+    }
+
+
+    // iterate all communicator plugins and start them
+    std::list<std::string>::iterator iter = sharedLibraryNameList.begin();
+    std::list<std::string>::iterator iterEnd = sharedLibraryNameList.end();
+
+    for (; iter != iterEnd; ++iter)
+    {
+       DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Loading Hook plugin"),DLT_STRING(iter->c_str()));
+
+        BaseHook* (*createFunc)();
+        createFunc = getCreateFunction<BaseHook*()>(*iter);
+
+        if (!createFunc) {
+            DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Entry point of Communicator not found"));
+            continue;
+        }
+
+        BaseHook* HookPlugin = createFunc();
+
+        if (!HookPlugin) {
+               DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("HookPlugin initialization failed. Entry Function not callable"));
+            continue;
+        }
+
+               HookPlugin->registerHookEngine(this);
+               HookPlugin->registerAudioManagerCore(m_core);
+               HookPlugin->InitHook();
+               char pName[40];
+               HookPlugin->returnPluginName(pName);
+               DLT_LOG( AudioManager, DLT_LOG_INFO, DLT_STRING("Registered Hook Plugin:"), DLT_STRING(pName));
+        m_listofPlugins.push_back(HookPlugin);
+    }
+
 }
 
diff --git a/AudioManagerDaemon/PluginHandler.cpp b/AudioManagerDaemon/PluginHandler.cpp
deleted file mode 100644 (file)
index 478ce1f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * PluginHandler.cpp
- *
- *  Created on: Jul 15, 2011
- *      Author: blacky
- */
-
-#include "PluginHandler.h"
-
-PluginHandler::PluginHandler() {
-       // TODO Auto-generated constructor stub
-
-}
-
-PluginHandler::~PluginHandler() {
-       // TODO Auto-generated destructor stub
-}
-
diff --git a/AudioManagerDaemon/PluginHandler.h b/AudioManagerDaemon/PluginHandler.h
deleted file mode 100644 (file)
index 47525c6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * PluginHandler.h
- *
- *  Created on: Jul 15, 2011
- *      Author: blacky
- */
-
-#ifndef PLUGINHANDLER_H_
-#define PLUGINHANDLER_H_
-
-class PluginHandler {
-public:
-       PluginHandler();
-       virtual ~PluginHandler();
-};
-
-#endif /* PLUGINHANDLER_H_ */
index d2e5d22..d0d03f4 100644 (file)
@@ -27,10 +27,9 @@ SET(PLUGIN_STANDARD_HOOKS_SRCS_CXX
 )
 
 add_library(PluginHookStandard SHARED ${PLUGIN_STANDARD_HOOKS_SRCS_CXX})
-add_library(PluginHookStandard ${PLUGIN_STANDARD_HOOKS_SRCS_CXX})
+add_library(PluginHookStandardStatic ${PLUGIN_STANDARD_HOOKS_SRCS_CXX})
 
-TARGET_LINK_LIBRARIES(PluginHookStandard 
-)
+#TARGET_LINK_LIBRARIES(PluginHookStandard)
 
 #add a target to generate API documentation with Doxygen
 find_package(Doxygen)
index 4401c37..4f71b9f 100644 (file)
@@ -47,7 +47,7 @@ genError_t StandardHookPlugin::InitHook(void) {
 }
 
 genError_t StandardHookPlugin::returnPluginName(char* name) {
-       strcpy(name,"Test Plugin");
+       strcpy(name,"Standard Plugin");
        return GEN_OK;
 }
 
index dbfe164..27c28d9 100644 (file)
@@ -54,11 +54,11 @@ public:
 
 };
 
-extern "C" BaseHook* StandardHookPluginFactory() {
+extern "C" BaseHook* PluginHookStandardFactory() {
     return new StandardHookPlugin();
 }
 
-extern "C" void destroyStandardHookPlugin(StandardHookPlugin* hook) {
+extern "C" void destroyPluginHookStandard(StandardHookPlugin* hook) {
     delete hook;
 }