Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
6cfa328d
Commit
6cfa328d
authored
Jan 25, 2009
by
Emmanuel Milou
Browse files
Add the dynamic loading for the plugin framework; integate unit tests
parent
26393bbe
Changes
10
Hide whitespace changes
Inline
Side-by-side
globals.mak
View file @
6cfa328d
# Global variables
src
=
$(top_srcdir)
sflcodecdir
=
$(libdir)
/sflphone/codecs
sflplugindir
=
$(libdir)
/sflphone/plugins
PJSIP_LIBS
=
-lpjnath-sfl
-lpjsua-sfl
-lpjsip-sfl
-lpjmedia-sfl
-lpjsip-simple-sfl
-lpjsip-ua-sfl
-lpjmedia-codec-sfl
-lpjlib-util-sfl
-lpj-sfl
...
...
@@ -16,5 +17,6 @@ AM_CPPFLAGS = \
@SIP_CFLAGS@
\
@DBUSCPP_CFLAGS@
\
-DCODECS_DIR
=
\"
"
$(sflcodecdir)
"
\"
\
-DPLUGINS_DIR
=
\"
"
$(sflplugindir)
"
\"
\
-DENABLE_TRACE
src/Makefile.am
View file @
6cfa328d
...
...
@@ -87,6 +87,7 @@ libsflphone_la_LIBADD = \
./audio/libaudio.la
\
./dbus/libdbus.la
\
./config/libconfig.la
\
./plug-in/libplugin.la
\
$(IAX_LIBS)
libsflphone_la_SOURCES
=
src/plug-in/Makefile.am
View file @
6cfa328d
include
../../globals.mak
noinst_LTLIBRARIES
=
libplugin.la
libplugin_la_SOURCES
=
\
pluginmanager.cpp
plugin.cpp
pluginmanager.cpp
\
plugin.h
src/plug-in/plugin.cpp
View file @
6cfa328d
#include
"plugin.h"
Plugin
::
Plugin
(
const
std
::
string
&
filename
)
::
sflphone
::
Plugin
::
Plugin
(
const
std
::
string
&
filename
UNUSED
)
{
//TODO IMPLEMENT
}
Plugin
::
Plugin
(
const
Plugin
&
plugin
)
::
sflphone
::
Plugin
::
Plugin
(
const
Plugin
&
plugin
UNUSED
)
{
//TODO IMPLEMENT
}
Plugin
::~
Plugin
()
::
sflphone
::
Plugin
::~
Plugin
()
{
//TODO IMPLEMENT
}
int
Plugin
::
getCoreVersion
(
void
)
int
::
sflphone
::
Plugin
::
getCoreVersion
(
void
)
const
{
//TODO IMPLEMENT
return
1
;
}
void
Plugin
::
registerPlugin
(
PluginManager
&
)
void
::
sflphone
::
Plugin
::
registerPlugin
(
PluginManager
&
)
{
//TODO IMPLEMENT
}
src/plug-in/plugin.h
View file @
6cfa328d
...
...
@@ -3,6 +3,8 @@
#include
<string>
#include
"global.h"
/*
* @file plugin.h
* @brief Define a plugin object
...
...
@@ -15,21 +17,21 @@ class PluginManager;
class
Plugin
{
public:
Plugin
(
const
std
::
string
&
file
name
);
Plugin
(
const
Plugin
&
plugin
);
~
Plugin
()
;
Plugin
(
const
std
::
string
&
name
);
//
Plugin( const Plugin &plugin );
virtual
~
Plugin
()
{}
public:
/**
* Return the minimal core version required so that the plugin could work
* @return int The version required
*/
int
getCoreVersion
()
const
;
virtual
int
getCoreVersion
()
const
=
0
;
/**
* Register the plugin to the plugin manager
*/
void
registerPlugin
(
PluginManager
&
);
virtual
void
registerPlugin
(
PluginManager
&
)
=
0
;
private:
Plugin
&
operator
=
(
const
Plugin
&
plugin
);
...
...
src/plug-in/pluginmanager.cpp
View file @
6cfa328d
#include
<dirent.h>
#include
<dlfcn.h>
#include
"pluginmanager.h"
void
::
sflphone
::
PluginManager
::
loadPlugins
(
const
std
::
string
&
path
)
::
sflphone
::
PluginManager
::
PluginManager
()
:
_loadedPlugins
()
{
_instance
=
this
;
}
::
sflphone
::
PluginManager
::~
PluginManager
()
{
_instance
=
0
;
}
int
::
sflphone
::
PluginManager
::
loadPlugins
(
const
std
::
string
&
path
)
{
std
::
string
pluginDir
,
current
;
::
sflphone
::
Plugin
*
plugin
;
DIR
*
dir
;
dirent
*
dirStruct
;
int
result
=
0
;
const
std
::
string
pDir
=
".."
;
const
std
::
string
cDir
=
"."
;
/* The directory in which plugins are dropped. Default: /usr/lib/sflphone/plugins/ */
(
path
==
""
)
?
pluginDir
=
std
::
string
(
PLUGINS_DIR
).
append
(
"/"
)
:
pluginDir
=
path
;
_debug
(
"Loading plugins from %s...
\n
"
,
pluginDir
.
c_str
());
dir
=
opendir
(
pluginDir
.
c_str
()
);
/* Test if the directory exists or is readable */
if
(
dir
){
/* Read the directory */
while
(
(
dirStruct
=
readdir
(
dir
))
){
/* Get the name of the current item in the directory */
current
=
dirStruct
->
d_name
;
/* Test if the current item is not the parent or the current directory */
if
(
current
!=
pDir
&&
current
!=
cDir
){
loadDynamicLibrary
(
current
);
result
++
;
}
}
}
/* Close the directory */
closedir
(
dir
);
return
result
;
}
::
sflphone
::
Plugin
*
::
sflphone
::
PluginManager
::
isPluginLoaded
(
const
std
::
string
&
name
)
{
//TODO IMPLEMENT
if
(
_loadedPlugins
.
empty
())
return
NULL
;
/* Use an iterator on the loaded plugins map */
pluginMap
::
iterator
iter
;
iter
=
_loadedPlugins
.
begin
();
while
(
iter
!=
_loadedPlugins
.
end
()
)
{
if
(
iter
->
first
==
name
)
{
/* Return the associated plugin */
return
iter
->
second
;
}
iter
++
;
}
/* If we are here, it means that the plugin we were looking for has not been loaded */
return
NULL
;
}
void
*
::
sflphone
::
PluginManager
::
loadDynamicLibrary
(
const
std
::
string
&
filename
)
{
void
*
pluginHandlePtr
=
NULL
;
const
char
*
error
;
_debug
(
"Loading dynamic library %s
\n
"
,
filename
.
c_str
());
#if defined(Q_OS_UNIX)
/* Load the library */
pluginHandlePtr
=
dlopen
(
filename
.
c_str
(),
RTLD_LAZY
);
if
(
!
pluginHandlePtr
)
{
error
=
dlerror
();
_debug
(
"Error while opening plug-in: %s
\n
"
,
error
);
}
dlerror
();
#endif
return
pluginHandlePtr
;
}
void
::
sflphone
::
PluginManager
::
unloadDynamicLibrary
(
void
*
pluginHandlePtr
)
{
dlclose
(
pluginHandlePtr
);
dlerror
();
}
::
sflphone
::
PluginManager
*
::
sflphone
::
PluginManager
::
_instance
=
0
;
src/plug-in/pluginmanager.h
View file @
6cfa328d
...
...
@@ -7,6 +7,7 @@
*/
#include
"plugin.h"
#include
"global.h"
#include
<map>
#include
<string>
...
...
@@ -16,17 +17,55 @@ namespace sflphone {
class
PluginManager
{
public:
/**
* Default constructor
*/
PluginManager
();
/**
* Destructor
*/
~
PluginManager
();
/**
* Returns the unique instance of the plugin manager
*/
static
PluginManager
*
instance
();
/**
* Load all the plugins found in a specific directory
* @param path The absolute path to the directory
* @return int The number of items loaded
*/
int
loadPlugins
(
const
std
::
string
&
path
=
""
);
/**
* Check if a plugin has been already loaded
* @param name The name of the plugin looked for
* @return Plugin* The pointer on the plugin or NULL if not found
*/
void
loadPlugins
(
const
std
::
string
&
path
);
Plugin
*
isPluginLoaded
(
const
std
::
string
&
name
);
private:
/* Map of plugins associated by their string name */
typedef
std
::
map
<
std
::
string
,
::
sflphone
::
Plugin
>
pluginMap
;
/**
* Load a unix dynamic/shared library
* @param filename The path to the dynamic/shared library
* @return void* A pointer on it
*/
void
*
loadDynamicLibrary
(
const
std
::
string
&
filename
);
/**
* Unload a unix dynamic/shared library
* @param pluginHandleptr The pointer on the loaded plugin
*/
void
unloadDynamicLibrary
(
void
*
pluginHandlePtr
);
/* Map of plugins associated by their string name */
typedef
std
::
map
<
std
::
string
,
::
sflphone
::
Plugin
*>
pluginMap
;
pluginMap
_loadedPlugins
;
/* The unique static instance */
static
PluginManager
*
_instance
;
};
}
...
...
test/Makefile.am
View file @
6cfa328d
include
../globals.mak
bin_PROGRAMS
=
configurationTester
bin_PROGRAMS
=
configurationTester
pluginmanagerTester
OBJECT_FILES
=
\
../src/sflphoned-managerimpl.o
\
...
...
@@ -16,6 +16,7 @@ OBJECT_FILES= \
../src/sflphoned-iaxaccount.o
\
../src/sflphoned-eventthread.o
\
../src/sflphoned-useragent.o
\
../src/plug-in/pluginmanager.o
\
../src/sflphoned-samplerateconverter.o
configurationTester_SOURCES
=
\
...
...
@@ -23,6 +24,11 @@ configurationTester_SOURCES = \
configurationTest.h
\
TestMain.cpp
pluginmanagerTester_SOURCES
=
\
pluginmanagerTest.h
\
pluginmanagerTest.cpp
\
TestMain.cpp
configurationTester_LDADD
=
\
../src/libsflphone.la
\
$(SFLPHONE_LIBS)
$(ZEROCONFLIB)
$(LIB_DNSSD)
$(IAX_LIBS)
\
...
...
@@ -36,4 +42,18 @@ configurationTester_LDADD = \
@SAMPLERATE_LIBS@
\
$(PJSIP_LIBS)
\
$(OBJECT_FILES)
pluginmanagerTester_LDADD
=
\
../src/libsflphone.la
\
$(SFLPHONE_LIBS)
$(ZEROCONFLIB)
$(LIB_DNSSD)
$(IAX_LIBS)
\
@ALSA_LIBS@
\
@PULSEAUDIO_LIBS@
\
@CPPUNIT_LIBS@
\
@CCEXT2_LIBS@
\
@CCGNU2_LIBS@
\
@CCRTP_LIBS@
\
@DBUSCPP_LIBS@
\
@SAMPLERATE_LIBS@
\
$(PJSIP_LIBS)
\
$(OBJECT_FILES)
test/pluginmanagerTest.cpp
0 → 100644
View file @
6cfa328d
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include
<stdio.h>
#include
<sstream>
#include
"pluginmanagerTest.h"
using
std
::
cout
;
using
std
::
endl
;
void
PluginManagerTest
::
setUp
(){
// Instanciate the plugin manager object
_pm
=
new
::
sflphone
::
PluginManager
();
}
void
PluginManagerTest
::
testLoadPluginDirectory
(){
_pm
->
loadPlugins
();
}
void
PluginManagerTest
::
testNonloadedPlugin
(){
CPPUNIT_ASSERT
(
_pm
->
isPluginLoaded
(
"test"
)
==
NULL
);
}
void
PluginManagerTest
::
tearDown
(){
// Delete the plugin manager object
delete
_pm
;
_pm
=
NULL
;
}
test/pluginmanagerTest.h
0 → 100644
View file @
6cfa328d
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Cppunit import
#include
<cppunit/extensions/HelperMacros.h>
#include
<cppunit/TestCaller.h>
#include
<cppunit/TestCase.h>
#include
<cppunit/TestSuite.h>
#include
<assert.h>
// Application import
#include
"plug-in/pluginmanager.h"
/*
* @file pluginManagerTest.cpp
* @brief Regroups unitary tests related to the plugin manager.
*/
#ifndef _PLUGINMANAGER_TEST_
#define _PLUGINMANAGER_TEST_
class
PluginManagerTest
:
public
CppUnit
::
TestCase
{
/*
* Use cppunit library macros to add unit test the factory
*/
CPPUNIT_TEST_SUITE
(
PluginManagerTest
);
CPPUNIT_TEST
(
testLoadPluginDirectory
);
CPPUNIT_TEST
(
testNonloadedPlugin
);
CPPUNIT_TEST_SUITE_END
();
public:
PluginManagerTest
()
:
CppUnit
::
TestCase
(
"Plugin Manager Tests"
)
{}
/*
* Code factoring - Common resources can be initialized here.
* This method is called by unitcpp before each test
*/
void
setUp
();
/*
* Code factoring - Common resources can be released here.
* This method is called by unitcpp after each test
*/
inline
void
tearDown
();
void
testLoadPluginDirectory
();
void
testNonloadedPlugin
();
private:
::
sflphone
::
PluginManager
*
_pm
;
};
/* Register our test module */
CPPUNIT_TEST_SUITE_REGISTRATION
(
PluginManagerTest
);
#endif
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment