diff -r c39a6cfd1fb9 -r be09cf1f39dd smf/smfservermodule/smfserver/pluginmgr/smfpluginmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smf/smfservermodule/smfserver/pluginmgr/smfpluginmanager.cpp Tue May 18 17:37:12 2010 +0530 @@ -0,0 +1,1051 @@ +/** + * Copyright (c) 2010 Sasken Communication Technologies Ltd. + * All rights reserved. + * This component and the accompanying materials are made available + * under the terms of the "Eclipse Public License v1.0" + * which accompanies this distribution, and is available + * at the URL "http://www.eclipse.org/legal/epl-v10.html" + * + * Initial Contributors: + * Chandradeep Gandhi, Sasken Communication Technologies Ltd - Initial contribution + * + * Contributors: + * Manasij Roy, Nalina Hariharan + * + * Description: + * The Plugin Manager class manages the loading and unloading of plug-ins + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smfpluginmanager.h" +#include "smfpluginmanagerutil.h" +#include "smftransportmanagerutil.h" + +// Static data initialisation +SmfPluginManager* SmfPluginManager::m_myInstance = NULL; + + +/** + * Method to get the instance of SmfPluginManager class + * @param aServer The Smf server instance + * @return The instance of SmfPluginManager class + */ +SmfPluginManager* SmfPluginManager::getInstance ( SmfServer *aServer) + { + if(NULL == m_myInstance) + m_myInstance = new SmfPluginManager(aServer); + return m_myInstance; + } + + +/** + * Constructor with default argument + * @param aServer The Smf server instance + */ +SmfPluginManager::SmfPluginManager ( SmfServer *aServer ) + { + // Save the server instance + m_server = aServer; + + m_server->writeLog("Inside SmfPluginManager::SmfPluginManager()"); + + // initialize the file watcher to monitor plugin addition/upgradation/removal + initializeFileWatcher ( ); + + // create a database to store the folder structure of the path "c://resource//qt//plugins" + initializeSmfPluginDataBase ( ); + + // create teh Plugin Manager utility class instance + m_util = new SmfPluginManagerUtil(this); + + // Get handle to the Transport MAnager utility instance + m_transMngrUtil = SmfTransportManagerUtil::getInstance(); + } + + +/** + * Destructor + */ +SmfPluginManager::~SmfPluginManager ( ) + { + m_server->writeLog("Inside SmfPluginManager::~SmfPluginManager()"); + if(m_fileWatcher) + delete m_fileWatcher; + + if(m_tempStruct) + delete m_tempStruct; + + if(m_waitingPluginHash.count() > 0) + { + foreach(SmfWaitingPluginInfoStruc *str, m_waitingPluginHash.values()) + delete str; + } + + if(m_util) + delete m_util; + + if(m_pluginDataBase.isOpen()) + { + m_pluginDataBase.close(); + m_pluginDataBase.removeDatabase("SmfPluginsInfoDatabase"); + } + + // unload all loaded plugins + unload(m_pluginLoaderHash.keys()); + + if(m_myInstance) + delete m_myInstance; + } + + +/** + * Method called by Smf server to create a web query. + * Plugin Manager calls the appropriate web query creation method + * using the aOperation and aInputData parameters. Once the web request + * is ready, it calls the appropriate methods exposed by the Transport + * Manager to send the network request. + * @param aSessionID The session ID provided by Smf Server + * @param aPluginID The plugin ID that need to perform this operation + * @param aOperation The type of operation to be performed + * @param aInputData The data required to create the web query + * @return SmfPluginManagerResult The result of the operation + * @see smfglobal.h + */ +SmfPluginManagerResult SmfPluginManager::createRequest ( const quint32& aSessionID, + const QString& aPluginID, + const SmfRequestTypeID& aOperation, + QByteArray& aInputData ) + { + m_server->writeLog("Inside SmfPluginManager::createRequest()"); + + SmfPluginManagerResult result = SmfPluginUnknownError; + + // Load the plugin + QObject *plugin = load(aPluginID, result); + + // Check if plugin is loaded + if(plugin && (SmfPluginLoaded == result)) + { + m_server->writeLog("Plugin loaded"); + SmfPluginBase* instance = qobject_cast(plugin); + + if(instance) + { + // Get the registration token of the plugin + QString regToken = instance->getProviderInfo()->smfRegistrationId(); + QList urlList; + SmfPluginRequestData reqData; + + // check if the plugin is authorised (with CSM) + if( authorisePlugin(regToken, urlList )) + { + m_server->writeLog("Plugin authorised"); + + // call the utility method to create plugin specific request + m_util->createRequest(plugin, aOperation, aInputData, reqData, result); + + // If the request is created successfully, call the TM method to send the request + if( SmfPluginRequestCreated == result ) + { + m_server->writeLog("Plugin request creation successful"); + m_tempStruct = new SmfWaitingPluginInfoStruc(); + m_tempStruct->iSessionID = aSessionID; + m_tempStruct->iPluginId = aPluginID; + m_tempStruct->iInstance = instance; + m_tempStruct->iOperation = aOperation; + m_tempStruct->iInputData = aInputData; + m_tempStruct->iUrlList = urlList; + + // send the request + sendRequest ( reqData, result, urlList ); + } + } + + else + { + // plugin not authorised, so unload + m_server->writeLog("Plugin not authorised!!!"); + unload(instance); + result = SmfPluginNotAuthorised; + } + } + else + { + // plugin instance cannot be casted, so unload + m_server->writeLog("Plugin instance cannot be casted to SmfPluginBase*!!!"); + unload(instance); + result = SmfPluginLoadError; + } + } + + else + { + // plugin not loaded + m_server->writeLog("Plugin not loaded!!!"); + result = SmfPluginLoadError; + } + + return result; + } + + +/** + * Method called by Transport Manager when network response is available + * @param aTransportResult The result of Transport Operation + * @param aReply The QNetworkReply instance that requested + * this transaction + * @param aResponse The network response data, may be NULL for error + */ +void SmfPluginManager::responseAvailable ( + const SmfTransportResult &aTransportResult, + QNetworkReply *aReply, + QByteArray *aResponse ) + { + m_server->writeLog("Inside SmfPluginManager::responseAvailable()"); + + // For request success or For request cancellation + if((SmfTransportOpNoError == aTransportResult) || + (SmfTransportOpOperationCanceledError == aTransportResult)) + { + m_server->writeLog("no transport error/ cancellation"); + + // get the details of the plugin which made this request + SmfWaitingPluginInfoStruc* info = m_waitingPluginHash.value(aReply); + quint32 sessionId = m_waitingPluginHash.value(aReply)->iSessionID; + QString pluginId = m_waitingPluginHash.value(aReply)->iPluginId; + SmfRequestTypeID operation = m_waitingPluginHash.value(aReply)->iOperation; + QByteArray inputData = m_waitingPluginHash.value(aReply)->iInputData; + + QVariant result; + SmfPluginRetType retType = SmfRequestError; + SmfResultPage pageResult; + + m_server->writeLog("Before m_util->responseAvailable"); + + // call the utility method to send response to appropriate plugins + SmfPluginManagerResult retValue = m_util->responseAvailable( info->iInstance, operation, + aTransportResult, aResponse, &result, retType, pageResult ); + + // remove the plugin from the waiting list + delete m_waitingPluginHash.value(aReply); + m_waitingPluginHash.remove(aReply); + + QByteArray arr; + QDataStream stream(&arr, QIODevice::ReadWrite); + if( SmfPluginResponseParsed == retValue ) + { + m_server->writeLog("Parsing successful"); + + // serialize the response to suitable class and pass the data to server + serializeResult(operation, &result, stream); + + ////TODO:- send error in enums-by manasij + // Send the response data to the server + m_server->resultsAvailable(sessionId, &arr, SmfNoError); + } + + // Send the request again + else if( SmfPluginSendRequestAgain == retValue ) + { + m_server->writeLog("Send request again"); + + // create the request again (with same paramaters) + retValue = createRequest( sessionId, pluginId, operation, inputData ); + } + + // Error + else + { + m_server->writeLog("Parsing failed!!"); + + // Error in parsing, sent to server + m_server->resultsAvailable(sessionId, &arr, SmfpluginResponseParseFailure); + } + + // delete aReply later, when event loop is re-entered + aReply->deleteLater(); + } + + // Any other error + else + { + m_server->writeLog("Error in SmfPluginManager::responseAvailable, Transport failure code : "); + QString err = QString::number(aTransportResult); + m_server->writeLog(err); + + //Added by manasij, send all kind of errors to the server + //TODO:- to be refined by PM owner + quint32 sessionId = m_waitingPluginHash.value(aReply)->iSessionID; + QByteArray arr; + m_server->resultsAvailable(sessionId, &arr, SmftransportInitNetworkNotAvailable); + } + } + + +/** + * Method to cancel the service request + * @param aPluginId The plugin whose current operation + * is to be cancelled + */ +bool SmfPluginManager::cancelRequest ( const QString& aPluginId ) + { + bool retValue = false; + m_server->writeLog("Inside SmfPluginManager::cancelRequest()"); + + // Get the plugin for which cancel is requested + foreach(SmfWaitingPluginInfoStruc* iPluginInfo, m_waitingPluginHash.values()) + { + if( 0 == iPluginInfo->iPluginId.compare(aPluginId)) + { + m_server->writeLog("Plugin to be cancelled found in the waiting list"); + + // Notify Transport Manager + m_transMngrUtil->cancelRequest(m_waitingPluginHash.key(iPluginInfo)); + + // Notify the plugin that the request has been cancelled + SmfPluginRetType retType; + SmfResultPage pageResult; + SmfPluginError ret = iPluginInfo->iInstance->responseAvailable( SmfTransportOpCancelled, + NULL, NULL, retType, pageResult ); + + // Remove that plugin from the waiting list + delete (m_waitingPluginHash.value(m_waitingPluginHash.key(iPluginInfo))); + m_waitingPluginHash.remove(m_waitingPluginHash.key(iPluginInfo)); + + if(SmfPluginErrNone == ret) + retValue = true; + } + //else , cancel requested for a plugin which is not loaded, do nothing + else + { + m_server->writeLog("Plugin to be cancelled not found in the waiting list!!! - do nothing"); + retValue = false; + } + } + return retValue; + } + + +/** + * Method called to initialize the file watcher watching the file + * system for adition/upgradation/removal of plugins + */ +void SmfPluginManager::initializeFileWatcher ( ) + { + m_server->writeLog("Inside SmfPluginManager::initializeFileWatcher()"); + + // Create the file watcher for the plugins in /Smf folder of the Qt plugin directory + m_fileWatcher = new QFileSystemWatcher(this); + + // Get the directory having the Qt plugin stubs + QDir dir(QLibraryInfo::location(QLibraryInfo::PluginsPath)); + + // If Smf folder exists + if(dir.cd("smf/plugin")) + { + // Add each service provider folders to the file watcher + foreach(QString folder, dir.entryList(QDir::AllDirs)) + { + dir.cd(folder); + m_fileWatcher->addPath(dir.absolutePath()); + dir.cdUp(); + } + } + else + m_fileWatcher->addPath(dir.absolutePath()); + } + + + +/** + * Method called to initialize the database holding the plugin + * directory sructure information. This is called only once when + * the Plugin Manager is instantiated. + * This method creates and updates m_pluginIdPathHash member + * of this class + */ +bool SmfPluginManager::initializeSmfPluginDataBase ( ) + { + m_server->writeLog("Inside SmfPluginManager::initializeSmfPluginDataBase()"); + + // Find QSQLite driver and create a connection to database + m_pluginDataBase.removeDatabase("SmfPluginsInfoDatabase"); + m_pluginDataBase = QSqlDatabase::addDatabase("QSQLITE"); + m_pluginDataBase.setDatabaseName("SmfPluginsInfoDatabase"); + + // Open the database + bool opened = m_pluginDataBase.open(); + if(!opened) + return false; + + m_server->writeLog("Database opened"); + + // Create a query to create the DB table for Plugin Manager (if it doesn't exists) + QSqlQuery query; + bool tableCreated = false; + + tableCreated = query.exec("CREATE TABLE IF NOT EXISTS pluginDetails (" + "pluginId TEXT PRIMARY KEY, interfaceName TEXT, serviceProvider TEXT, " + "description TEXT, serviceUrl TEXT, authAppId TEXT)"); + + // Error - table not created, Plugin Manager might not work properly + if(!tableCreated) + { + m_server->writeLog("Table not created, error = "+query.lastError().text()); + return false; + } + + m_server->writeLog("Table created"); + + // Get the directory having the Qt plugin stubs + QDir dir(QLibraryInfo::location(QLibraryInfo::PluginsPath)); + + // If Smf folder exists + if(dir.cd("smf/plugin")) + { + m_server->writeLog("Smf/plugin folder exists"); + // Get each interface folders names + foreach(QString intfName, dir.entryList(QDir::AllDirs)) + { + dir.cd(intfName); + m_server->writeLog("Interface name : "+dir.dirName()); + + // Get each plugin in this folder + foreach(QString pluginName, dir.entryList(QDir::Files)) + { + m_server->writeLog("plugins for this Interface : "+pluginName); + + // load this plugin + QPluginLoader pluginLoader(dir.absoluteFilePath(pluginName)); + QObject *instance = pluginLoader.instance(); + if (instance) + { + m_server->writeLog("instance found"); + SmfPluginBase* plugin = qobject_cast(instance); + if (plugin) + { + m_server->writeLog("SmfPluginBase found"); + plugin->initialize(SmfPluginUtil::getInstance()); + + // get the plugin id + QString id = plugin->getProviderInfo()->pluginId(); + + // get the interface implemented by the plugin + QString intfImplemented = dir.dirName(); + intfImplemented.prepend("org.symbian.smf.plugin."); + m_server->writeLog("intfImplemented="); + m_server->writeLog(intfImplemented); + + // get the service provider + QString serProv = plugin->getProviderInfo()->serviceName(); + + //get the description + QString desc = plugin->getProviderInfo()->description(); + + // get the service URL + QString servURL = plugin->getProviderInfo()->serviceUrl().toString(); + + // get the authentication application id + QString str; + QStringList list; + QString authAppId = plugin->getProviderInfo()->authenticationApp( + str, list, QIODevice::ReadWrite); + + // Update m_pluginIdPathHash + m_pluginIdPathHash.insert(id, dir.absoluteFilePath(pluginName)); + + QSqlQuery rowInsertQuery; + + // insert into database + bool rowInserted = rowInsertQuery.exec(QString("INSERT INTO pluginDetails VALUES ('%1', " + "'%2', '%3', '%4', '%5', '%6')").arg(id).arg(intfImplemented).arg(serProv) + .arg(desc).arg(servURL).arg(authAppId)); + + if(rowInserted) + m_server->writeLog("This Plugin's information is added to database : "+id+"" + ", "+intfImplemented+", "+serProv); + else + m_server->writeLog("plugins data not written to database, error = "+query.lastError().text()); + } + else + { + m_server->writeLog("Plugin could not be converted to SmfpluginBase* - returning"); + + // Close the database + m_pluginDataBase.close(); + + return false; + } + + pluginLoader.unload(); + } + else + { + m_server->writeLog("Plugin could not be loaded - returning"); + + // Close the database + m_pluginDataBase.close(); + + return false; + } + } + dir.cdUp(); + } + } + else + m_server->writeLog("No Smf plugins installed!!!"); + + // Close the database + m_pluginDataBase.close(); + + return true; + } + + + +/** + * Method to load a plugin using its Plugin Id. + * @param aPluginId The unique ID of the plugin + * @param aLoadResult [out] Output paramater indicating the result + * of the loading + * @return The instance of the loaded plugin if loaded, else NULL + */ +QObject* SmfPluginManager::load ( const QString &aPluginId, + SmfPluginManagerResult &aLoadResult) + { + m_server->writeLog("Inside SmfPluginManager::load()"); + + QPluginLoader *pluginLoader; + + // Find the plugin Path + QString pluginPath = m_pluginIdPathHash.value(aPluginId); + + if(!pluginPath.isEmpty()) + { + // create the plugin loader and load the plugin + pluginLoader = new QPluginLoader(pluginPath); + SmfPluginBase *plugin = qobject_cast(pluginLoader->instance()); + + // If the plugin is loaded + if( pluginLoader->isLoaded() && plugin ) + { + // Initialize the plugin + plugin->initialize(SmfPluginUtil::getInstance()); + + // update the plugin loader and the loaded plugin lists + m_pluginLoaderHash.insertMulti(plugin, pluginLoader); + aLoadResult = SmfPluginLoaded; + m_server->writeLog("Plugin loaded"); + } + else + { + m_server->writeLog("Plugin not loaded"); + + // Plugin could not be loaded, error + aLoadResult = SmfPluginNotLoaded; + } + } + else + { + m_server->writeLog("Plugin not found"); + + // plugin not found in hash + aLoadResult = SmfPluginNotFound; + } + + return pluginLoader->instance(); + } + + +/** + * Method to unload a loaded plugin. Returns true if success, else + * returns false. + * @param aPlugin The plugin instance to be unloaded + * @return Returns true if success, else returns false + */ +bool SmfPluginManager::unload ( SmfPluginBase *aPlugin ) + { + m_server->writeLog("Inside SmfPluginManager::unload()"); + + // Get all the loaders for this plugin + QList loaderList = m_pluginLoaderHash.values(aPlugin); + bool unloaded = false; + + foreach(QPluginLoader *loader, loaderList) + { + // for each loader unload the plugin + unloaded = loader->unload(); + + // delete the instance of the loader + delete loader; + loader = NULL; + } + + // Remove the plugin and its associated loaders from the Hash + m_pluginLoaderHash.remove(aPlugin); + return unloaded; + } + + +/** + * Method to unload the list of loaded plugins. Returns true if all are + * success, else returns false if any one fails. + * @param aPluginList The list of instances for all plugins that are + * to be unloaded + * @return Returns true if all are success, else returns false if any + * one fails. + */ +bool SmfPluginManager::unload ( const QList &aPluginList) + { + m_server->writeLog("Inside SmfPluginManager::unload() - overloaded fn"); + //unload all the required plugins + bool unloaded = true; + + foreach(SmfPluginBase *plugin, aPluginList) + { + // unload individual plugins in the list + bool ret = unload(plugin); + + // indicate error if any one of the plugin failed to unload + if(!ret) + unloaded = ret; + } + return unloaded; + } + + +/** + * Method that calls the Transport Manager Utility class method to + * send the request created by the plugins over the network + * @param aReqData The request data created by the plugin + * @param aResult [out] The output parameter indicating the result + * of this method + * @param aUrlList The list of accessible Urls for this plugin + * @see smfglobal.h + */ +void SmfPluginManager::sendRequest ( SmfPluginRequestData &aReqData, + SmfPluginManagerResult &aResult, + const QList &aUrlList ) + { + m_server->writeLog("Inside SmfPluginManager::sendRequest()"); + + QNetworkReply* reply; + bool sopCompliant = false; + + // Check the type of Http operation to be performed + switch(aReqData.iHttpOperationType) + { + // Http HEAD + case QNetworkAccessManager::HeadOperation: + reply = m_transMngrUtil->head(aReqData.iNetworkRequest, aUrlList, sopCompliant); + break; + + // Http GET + case QNetworkAccessManager::GetOperation: + reply = m_transMngrUtil->get(aReqData.iNetworkRequest, aUrlList, sopCompliant); + break; + + // Http PUT + case QNetworkAccessManager::PutOperation: + reply = m_transMngrUtil->put(aReqData.iNetworkRequest, aReqData.iPostData->buffer(), aUrlList, sopCompliant); + break; + + // Http POST + case QNetworkAccessManager::PostOperation: + reply = m_transMngrUtil->post(aReqData.iNetworkRequest, aReqData.iPostData->buffer(), aUrlList, sopCompliant); + break; + + // Http DELETE + case QNetworkAccessManager::DeleteOperation: + reply = m_transMngrUtil->deleteResource(aReqData.iNetworkRequest, aUrlList, sopCompliant); + break; + + default: + aResult = SmfPluginUnknownService; + return; + } + + if( sopCompliant ) + { + if( reply ) + { + // SOP compliant, sending successful + m_waitingPluginHash.insert(reply, m_tempStruct); + m_tempStruct = NULL; + aResult = SmfPluginNoError; + + m_server->writeLog("No error, request sent"); + + } + // reply is NULL, sending failed + else + { + m_server->writeLog("QNEtrworkReply returned error - not sent"); + aResult = SmfPluginRequestSendingFailed; + } + } + + // SOP violation + else + { + m_server->writeLog("SOP checking failed"); + aResult = SmfPluginSOPCheckFailed; + } + } + + +/** + * Method that checks if a plugin is authorised to make a request. + * This method communicates with Credential and Settings Manager + * through Smf server, giving the registration token and getting + * the valid url list if available for this plugin. + * @param aRegToken The registration token given by the plugin + * @param aUrlList [out] The list of Urls that the plugin can send + * request to (to be filled by CSM) + * @return Returns true if plugin is authorised, else returns false. + */ +bool SmfPluginManager::authorisePlugin( const QString &aRegToken, + QList &aUrlList ) + { + Q_UNUSED(aRegToken) + m_server->writeLog("Inside SmfPluginManager::authorisePlugin()"); + +#ifdef CSM_INTEGRATED +// Get the valid URL list from CSM, giving the reg token + if(m_server->authorisePlugin(aRegToken, aUrlList)) + return true; + else + return false; + +#else +// CSM STUBBING - start + QUrl url1 ("http://www.example.com"); + QUrl url2 ("http://api.facebook.com"); + QUrl url3 ("http://api.flickr.com"); + + aUrlList.append(url1); + aUrlList.append(url2); + aUrlList.append(url3); + + return true; +// CSM STUBBING - end +#endif + + } + + +/** + * Method to serialize the result of parsing (which is done by the + * plugins) to QByteArray to be sent to Smf server. + * @param aOperation The type of operation to be performed + * @param aResult The data to be serialized + * @param aDataStream Stream to be written + */ +void SmfPluginManager::serializeResult ( + const SmfRequestTypeID &aOperation, + QVariant* aResult, + QDataStream &aDataStream ) + { + m_server->writeLog("Inside SmfPluginManager::serializeResult()"); + + // Call the utlity class method to serialize the result + m_util->serializeResult(aOperation, aResult, aDataStream); + } + + +/** + * Method for the directoryChanged signal of QFileSystemWatcher. + * This will update the iPluginHash member and also the Plugin + * Information List. + * @param aPath The path of the directory that has changed + */ +void SmfPluginManager::directoryChanged ( const QString &aPath ) + { + m_server->writeLog("Inside SmfPluginManager::directoryChanged()"); + + // Create a QDir instance with the given path + QDir dir(aPath); + QString pluginId; + QString oldpluginId; + QString interfaceName; + QString serviceProv; + QString authAppId; + + // Get all the files in the directory at a specified path(sorted) + QStringList newPlugins = dir.entryList(QDir::Files, QDir::Name); + QStringList::const_iterator newListIterator = newPlugins.constBegin(); + + // Get all plugins who were in this path, before this directory was changed + QStringList availablePlugins = m_pluginIdPathHash.keys(aPath); + availablePlugins.sort(); + QStringList::const_iterator oldListIterator = availablePlugins.constBegin(); + + // Open the database + bool opened = m_pluginDataBase.open(); + if(!opened) + ;//return; + + // If plugin is changed + if( newPlugins.count() == availablePlugins.count() ) + { + // Check for equality + while( newListIterator != newPlugins.constEnd() ) + { + if( *newListIterator == *oldListIterator ) + { + newListIterator++; + oldListIterator++; + } + else + break; + } + // replace *oldListIterator with *newListIterator + QHash::iterator i = m_pluginIdPathHash.find(*oldListIterator); + m_pluginIdPathHash.insert(*newListIterator, i.value()); + m_pluginIdPathHash.remove(*oldListIterator); + + // Also update database with *newListIterator + QSqlQuery updateQuery; + + bool updated = updateQuery.exec(QString("UPDATE pluginDetails SET pluginId = '%1' " + "WHERE pluginId = '%2'").arg(*newListIterator).arg(*oldListIterator)); + if (!updated) + m_server->writeLog("Database table not updated, error = "+updateQuery.lastError().text()); + + + // Get the new and old plugin Ids + pluginId = *newListIterator; + oldpluginId = *oldListIterator; + + // Load the plugin and get its service provider name + SmfPluginManagerResult result; + SmfPluginBase* instance = qobject_cast(load(pluginId, result)); + + if(instance && (SmfPluginLoaded == result)) + { + instance->initialize(SmfPluginUtil::getInstance()); + serviceProv = instance->getProviderInfo()->serviceName(); + interfaceName = dir.dirName(); + } + + unload(instance); + // Inform server that plugin has been changed +#ifdef CSM_INTEGRATED + //Remove after Server Integration + m_server->pluginChanged(oldPluginId, newPluginId, interfaceName, serviceProv); +#endif + } + + // If plugin is added + else if(newPlugins.count() > availablePlugins.count()) + { + // Check for equality + while( oldListIterator != availablePlugins.constEnd() ) + { + if( *newListIterator == *oldListIterator ) + { + newListIterator++; + oldListIterator++; + } + else + break; + } + // replace *oldListIterator with *newListIterator + m_pluginIdPathHash.insert(*newListIterator, aPath); + + // Get the plugin Id + pluginId = *newListIterator; + + // Load the plugin and get its service provider name + SmfPluginManagerResult result; + SmfPluginBase* instance = qobject_cast(load(pluginId, result)); + + if(instance && (SmfPluginLoaded == result)) + { + instance->initialize(SmfPluginUtil::getInstance()); + serviceProv = instance->getProviderInfo()->serviceName(); + interfaceName = dir.dirName(); + interfaceName.prepend("org.symbian.smf.plugin."); + QString prgm; + QStringList list; + authAppId = instance->getProviderInfo()->authenticationApp(prgm, list, QIODevice::ReadWrite); + } + + unload(instance); + + // Also add to the database the value newListIterator and aPath + QSqlQuery insertRowQuery; + bool rowInserted = insertRowQuery.exec(QString("INSERT INTO pluginDetails VALUES " + "('%1', '%2', '%3', '%4')").arg(pluginId).arg(interfaceName).arg(serviceProv).arg(authAppId)); + + // Error + if (!rowInserted) + m_server->writeLog("Database table not inserted, error = "+insertRowQuery.lastError().text()); + + // Inform server that plugin has been added +#ifdef CSM_INTEGRATED + //Remove after Server Integration + m_server->pluginAdded(pluginId, interfaceName, serviceProv); +#endif + } + + // If plugin is removed + else //for newPlugins.count() < availablePlugins.count() + { + // Check for equality + while( newListIterator != newPlugins.constEnd() ) + { + if( *newListIterator == *oldListIterator ) + { + newListIterator++; + oldListIterator++; + } + else + break; + } + // remove *oldListIterator + m_pluginIdPathHash.remove(*oldListIterator); + + // Also remove oldListIterator from the database + QSqlQuery deleteRowQuery; + bool rowDeleted = deleteRowQuery.exec(QString("DELETE FROM pluginDetails WHERE pluginId = '%1'") + .arg(*oldListIterator)); + + // Error + if (!rowDeleted) + m_server->writeLog("Database table row not deleted, error = "+deleteRowQuery.lastError().text()); + + // Get the plugin Id + pluginId = *oldListIterator; + + // Load the plugin and get its service provider name + SmfPluginManagerResult result; + SmfPluginBase* instance = qobject_cast(load(pluginId, result)); + + if(instance && (SmfPluginLoaded == result)) + { + instance->initialize(SmfPluginUtil::getInstance()); + serviceProv = instance->getProviderInfo()->serviceName(); + interfaceName = dir.dirName(); + } + + unload(instance); + // Inform server that plugin has removed +#ifdef CSM_INTEGRATED + //Remove after Server Integration + m_server->pluginRemoved(pluginId, interfaceName, serviceProv); +#endif + } + // Close the database + m_pluginDataBase.close(); + } + + +/** + * Method to get the list of the SmfProvider for all the plugins that implement + * the mentioned Interface + * @param aInterface The interface for which list of plugins is required + * @param aMap The map of pluginID and its corresponding SmfProvider + */ +void SmfPluginManager::getPlugins(const QString& aInterface, QMap& aMap) + { + m_server->writeLog("Inside SmfPluginManager::getPlugins()"); + + // Open the database + bool opened = m_pluginDataBase.open(); + if(!opened) + { + m_server->writeLog("Data base not opened, exiting getplugins()"); + return; + } + + m_server->writeLog("Data base opened"); + + // Query the database for all pluginIDs that implement the given interface + QSqlQuery query(QString("SELECT pluginId, interfaceName, serviceProvider, description, " + "serviceUrl FROM pluginDetails where interfaceName = '%1'").arg(aInterface)); + + if (query.next()) + { + m_server->writeLog("Query is success"); + + SmfProvider prov; + + // get the pluginId + QString pluginId = query.value(0).toString(); + + // get the service type / interface name + QStringList servicetypes; + servicetypes.insert(0, query.value(1).toString()); + prov.serviceTypes(servicetypes); + + // Get the serv provider + QString servName = query.value(2).toString(); + prov.serviceName(servName); + + // Get the description + QString desc = query.value(3).toString(); + prov.description(desc); + + // Get the service URL + QUrl url(query.value(4).toString()); + prov.serviceUrl(url); + + aMap.insert(pluginId, prov); + } + else + m_server->writeLog("Data base query->next() returned false, error = "+query.lastError().text()); + + // Close the database + m_pluginDataBase.close(); + } + + +/** + * Method to get the pluginID for the mentioned interface and service provider + * @param aInterface The interface implemented by the plugin + * @param aProv The plugin's service provider + * @param aPluginId The required pluginID + */ +void SmfPluginManager::getPluginId(const QString& aInterface, const SmfProvider& aProv, QString& aPluginId) + { + m_server->writeLog("SmfPluginManager::getPluginId"); + + // Open the database + bool opened = m_pluginDataBase.open(); + if(!opened) + { + m_server->writeLog("Data base not opened, exiting"); + return; + } + + m_server->writeLog("Data base opened"); + + // Query the database for a pluginID with given interface name and service provider + QSqlQuery query(QString("SELECT pluginId FROM pluginDetails where interfaceName = '%1' AND " + "serviceProvider = '%2'").arg(aInterface).arg(aProv.serviceName())); + + if (query.next()) + { + m_server->writeLog("Query is success"); + + // get the pluginId + aPluginId = query.value(0).toString(); + } + else + m_server->writeLog("Data base query->next() returned false, error = "+query.lastError().text()); + + m_server->writeLog("returned pluginID = "+aPluginId); + + // Close the database + m_pluginDataBase.close(); + }