summaryrefslogtreecommitdiffstats
path: root/src/serviceframework/databasemanager_symbian.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/serviceframework/databasemanager_symbian.cpp')
-rw-r--r--src/serviceframework/databasemanager_symbian.cpp541
1 files changed, 541 insertions, 0 deletions
diff --git a/src/serviceframework/databasemanager_symbian.cpp b/src/serviceframework/databasemanager_symbian.cpp
new file mode 100644
index 00000000..575f4f88
--- /dev/null
+++ b/src/serviceframework/databasemanager_symbian.cpp
@@ -0,0 +1,541 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if defined(__WINS__) && !defined(SYMBIAN_EMULATOR_SUPPORTS_PERPROCESS_WSD)
+//Use DatabaseManager "directly" in emulators where per process WSD is not
+//supported.
+#include "databasemanager.cpp"
+#include "servicedatabase.cpp"
+#else //defined(__WINS__) && !defined(SYMBIAN_EMULATOR_SUPPORTS_PERPROCESS_WSD)
+
+#ifdef QTM_BUILD_UNITTESTS
+#include "servicedatabase.cpp"
+#endif
+
+#include "databasemanager_symbian_p.h"
+#include "clientservercommon.h"
+#include <qserviceinterfacedescriptor_p.h>
+#include <qserviceinterfacedescriptor.h>
+#include <qservicefilter.h>
+#include <QProcess>
+#include <QDebug>
+#include <s32mem.h>
+
+QTM_BEGIN_NAMESPACE
+
+/*
+ \class DatabaseManager
+ \ingroup servicesfw
+ \brief The database manager is responsible for receiving queries
+ about services and managing user and system scope databases in order to
+ respond to those queries.
+
+ The DatabaseManager provides operations for
+ - registering and unregistering services
+ - querying for services and interfaces
+ - setting and getting default interface implementations
+
+ and provides notifications by emitting signals for added
+ or removed services.
+
+ Implementation note:
+ When one of the above operations is first invoked a connection with the
+ appropriate database(s) is opened. This connection remains
+ open until the DatabaseManager is destroyed.
+
+ If the system scope database cannot be opened when performing
+ user scope operations. The operations are carried out as per normal
+ but only acting on the user scope database. Each operation invokation
+ will try to open a connection with the system scope database.
+
+ Terminology note:
+ When referring to user scope regarding operations, it generally
+ means access to both the user and system databases with the
+ data from both combined into a single dataset.
+ When referring to a user scope database it means the
+ user database only.
+*/
+
+/*
+ \fn DatabaseManager::DatabaseManager()
+
+ Constructor
+*/
+DatabaseManager::DatabaseManager()
+{
+ TInt err = iSession.Connect();
+ if (err != KErrNone)
+ qt_symbian_throwIfError(err);
+
+ iDatabaseManagerSignalMonitor = new DatabaseManagerSignalMonitor(*this, iSession);
+}
+
+/*
+ \fn DatabaseManager::~DatabaseManager()
+
+ Destructor
+*/
+DatabaseManager::~DatabaseManager()
+{
+ delete iDatabaseManagerSignalMonitor;
+ iSession.Close();
+}
+
+/*
+ \fn bool DatabaseManager::registerService(ServiceMetaDataResults &service, DbScope scope)
+
+ Adds the details \a service into the service database corresponding to
+ \a scope.
+
+ Returns true if the operation succeeded and false otherwise.
+ The last error is set when this function is called.
+*/
+bool DatabaseManager::registerService(ServiceMetaDataResults &service, DbScope scope)
+{
+ Q_UNUSED(scope);
+ return iSession.RegisterService(service);
+}
+
+/*
+ \fn bool DatabaseManager::unregisterService(const QString &serviceName, DbScope scope)
+
+ Removes the details of \a serviceName from the database corresponding to \a
+ scope.
+
+ Returns true if the operation succeeded, false otherwise.
+ The last error is set when this function is called.
+*/
+bool DatabaseManager::unregisterService(const QString &serviceName, DbScope scope)
+{
+ Q_UNUSED(scope);
+ return iSession.UnregisterService(serviceName);
+}
+
+/*
+ Removes the initialization specific information of \serviceName from the database.
+
+ Returns true if the operation succeeded, false otherwise.
+ The last error is set when this function is called.
+ */
+bool DatabaseManager::serviceInitialized(const QString &serviceName, DbScope scope)
+{
+ Q_UNUSED(scope);
+ return iSession.ServiceInitialized(serviceName);
+}
+
+/*
+ \fn QList<QServiceInterfaceDescriptor> DatabaseManager::getInterfaces(const QServiceFilter &filter, DbScope scope)
+
+ Retrieves a list of interface descriptors that fulfill the constraints specified
+ by \a filter at a given \a scope.
+
+ The last error is set when this function is called.
+*/
+QList<QServiceInterfaceDescriptor> DatabaseManager::getInterfaces(const QServiceFilter &filter, DbScope scope)
+{
+ Q_UNUSED(scope);
+ return iSession.Interfaces(filter);
+}
+
+
+/*
+ \fn QStringList DatabaseManager::getServiceNames(const QString &interfaceName, DbScope scope)
+
+ Retrieves a list of the names of services that provide the interface
+ specified by \a interfaceName.
+
+ The last error is set when this function is called.
+*/
+QStringList DatabaseManager::getServiceNames(const QString &interfaceName, DbScope scope)
+{
+ Q_UNUSED(scope);
+ return iSession.ServiceNames(interfaceName);
+}
+
+/*
+ \fn QServiceInterfaceDescriptor DatabaseManager::interfaceDefault(const QString &interfaceName, DbScope scope)
+
+ Returns the default interface implementation descriptor for a given
+ \a interfaceName and \a scope.
+
+ The last error is set when this function is called.
+*/
+QServiceInterfaceDescriptor DatabaseManager::interfaceDefault(const QString &interfaceName, DbScope scope)
+{
+ Q_UNUSED(scope);
+ return iSession.InterfaceDefault(interfaceName);
+}
+
+/*
+ \fn bool DatabaseManager::setInterfaceDefault(const QString &serviceName, const QString &interfaceName, DbScope scope)
+
+ Sets the default interface implemenation for \a interfaceName to the matching
+ interface implementation provided by \a service.
+
+ If \a service provides more than one interface implementation, the newest
+ version of the interface is set as the default.
+
+ Returns true if the operation was succeeded, false otherwise
+ The last error is set when this function is called.
+*/
+bool DatabaseManager::setInterfaceDefault(const QString &serviceName, const
+ QString &interfaceName, DbScope scope) {
+ Q_UNUSED(scope);
+ return iSession.SetInterfaceDefault(serviceName, interfaceName);
+}
+
+/*
+ \fn bool DatabaseManager::setInterfaceDefault(const QServiceInterfaceDescriptor &descriptor, DbScope scope)
+
+ Sets the interface implementation specified by \a descriptor to be the default
+ implementation for the particular interface specified in the descriptor.
+
+ Returns true if the operation succeeded, false otherwise.
+ The last error is set when this function is called.
+*/
+bool DatabaseManager::setInterfaceDefault(const QServiceInterfaceDescriptor &descriptor, DbScope scope)
+{
+ Q_UNUSED(scope);
+ return iSession.SetInterfaceDefault(descriptor);
+}
+
+/*
+ \fn void DatabaseManager::setChangeNotificationsEnabled(DbScope scope, bool enabled)
+
+ Sets whether change notifications for added and removed services are
+ \a enabled or not at a given \a scope.
+*/
+void DatabaseManager::setChangeNotificationsEnabled(DbScope scope, bool enabled)
+{
+ Q_UNUSED(scope);
+ iSession.SetChangeNotificationsEnabled(enabled);
+}
+
+DatabaseManagerSignalMonitor::DatabaseManagerSignalMonitor(
+ DatabaseManager& databaseManager, RDatabaseManagerSession& databaseManagerSession) :
+ CActive(EPriorityNormal),
+ iDatabaseManager(databaseManager), iDatabaseManagerSession(databaseManagerSession)
+{
+ CActiveScheduler::Add(this);
+ issueNotifyServiceSignal();
+}
+
+DatabaseManagerSignalMonitor::~DatabaseManagerSignalMonitor()
+{
+ Cancel();
+}
+
+void DatabaseManagerSignalMonitor::issueNotifyServiceSignal()
+{
+ iDatabaseManagerSession.NotifyServiceSignal(iStatus);
+ SetActive();
+}
+
+DBError DatabaseManager::lastError()
+{
+ return iSession.LastError();
+}
+
+void DatabaseManagerSignalMonitor::DoCancel()
+{
+ iDatabaseManagerSession.CancelNotifyServiceSignal();
+}
+
+void DatabaseManagerSignalMonitor::RunL()
+{
+ switch (iStatus.Int())
+ {
+ case ENotifySignalComplete:
+ {
+ QString serviceName = QString::fromUtf16(iDatabaseManagerSession.iServiceName.Ptr(), iDatabaseManagerSession.iServiceName.Length());
+
+ if ((DatabaseManager::State)iDatabaseManagerSession.iState() == DatabaseManager::EAdded)
+ {
+ emit iDatabaseManager.serviceAdded(serviceName, DatabaseManager::SystemScope);
+ }
+ else if ((DatabaseManager::State)iDatabaseManagerSession.iState() == DatabaseManager::ERemoved)
+ {
+ emit iDatabaseManager.serviceRemoved(serviceName, DatabaseManager::SystemScope);
+ }
+ issueNotifyServiceSignal();
+ break;
+ }
+ default:
+ {
+
+ }
+ break;
+ }
+}
+
+
+RDatabaseManagerSession::RDatabaseManagerSession()
+ : RSessionBase()
+ {
+ }
+
+TVersion RDatabaseManagerSession::Version() const
+ {
+ return TVersion(KServerMajorVersionNumber, KServerMinorVersionNumber, KServerBuildVersionNumber);
+ }
+
+TInt RDatabaseManagerSession::Connect()
+ {
+ TInt retryCount = 2;
+ for (;;)
+ {
+ TInt err = CreateSession(KDatabaseManagerServerName, TVersion(), 8, EIpcSession_Sharable);
+ if (err != KErrNotFound && err != KErrServerTerminated)
+ return err;
+ if (--retryCount == 0)
+ return err;
+ err = StartServer();
+ if (err != KErrNone && err != KErrAlreadyExists)
+ return err;
+ }
+ }
+
+TInt RDatabaseManagerSession::StartServer()
+ {
+ TInt ret = KErrNone;
+ TFindServer findServer(KDatabaseManagerServerName);
+ TFullName name;
+
+ if (findServer.Next(name) != KErrNone)
+ {
+ TRequestStatus status;
+ RProcess dbServer;
+ ret = dbServer.Create(KDatabaseManagerServerProcess, KNullDesC);
+ if(ret != KErrNone)
+ {
+ return ret;
+ }
+ dbServer.Rendezvous(status);
+ if(status != KRequestPending)
+ {
+ dbServer.Kill(KErrNone);
+ dbServer.Close();
+ return KErrGeneral;
+ }
+ else
+ {
+ dbServer.Resume();
+ }
+
+ User::WaitForRequest(status);
+ if(status != KErrNone)
+ {
+ dbServer.Close();
+ return status.Int();
+ }
+ dbServer.Close();
+ }
+
+ return ret;
+ }
+
+void RDatabaseManagerSession::Close()
+ {
+ RSessionBase::Close();
+ }
+
+bool RDatabaseManagerSession::RegisterService(ServiceMetaDataResults& aService)
+ {
+ QByteArray serviceByteArray;
+ QDataStream in(&serviceByteArray, QIODevice::WriteOnly);
+ in.setVersion(QDataStream::Qt_4_6);
+ in << aService;
+ TPtrC8 ptr8((TUint8*)(serviceByteArray.constData()), serviceByteArray.size());
+ TIpcArgs args(&ptr8, &iError);
+ SendReceive(ERegisterServiceRequest, args);
+
+ return (iError() == DBError::NoError);
+ }
+
+bool RDatabaseManagerSession::UnregisterService(const QString& aServiceName)
+ {
+ TPtrC serviceNamePtr(reinterpret_cast<const TUint16*>(aServiceName.utf16()));
+ TIpcArgs args(&serviceNamePtr, &iError);
+ SendReceive(EUnregisterServiceRequest, args);
+
+ return (iError() == DBError::NoError);
+ }
+
+bool RDatabaseManagerSession::ServiceInitialized(const QString& aServiceName)
+ {
+ TPtrC serviceNamePtr(reinterpret_cast<const TUint16*>(aServiceName.utf16()));
+ TIpcArgs args(&serviceNamePtr, &iError);
+ SendReceive(EServiceInitializedRequest, args);
+
+ return (iError() == DBError::NoError);
+ }
+
+
+QList<QServiceInterfaceDescriptor> RDatabaseManagerSession::Interfaces(const QServiceFilter& aFilter)
+ {
+ QByteArray filterByteArray;
+ QDataStream in(&filterByteArray, QIODevice::WriteOnly);
+ in.setVersion(QDataStream::Qt_4_6);
+ in << aFilter;
+ TPtrC8 ptr8((TUint8*)(filterByteArray.constData()), filterByteArray.size());
+ TPckgBuf<TInt> lengthPckg(0);
+ TIpcArgs args(&ptr8, &lengthPckg, &iError);
+ SendReceive(EGetInterfacesSizeRequest, args);
+
+ HBufC8* descriptorListBuf = HBufC8::New(lengthPckg());
+ TPtr8 ptrToBuf(descriptorListBuf->Des());
+ TIpcArgs args2(&ptrToBuf);
+ SendReceive(EGetInterfacesRequest, args2);
+
+ QByteArray descriptorListByteArray((const char*)ptrToBuf.Ptr(), ptrToBuf.Length());
+ QDataStream out(descriptorListByteArray);
+ QList<QServiceInterfaceDescriptor> descriptorList;
+ out >> descriptorList;
+
+ delete descriptorListBuf;
+
+ return descriptorList;
+ }
+
+QStringList RDatabaseManagerSession::ServiceNames(const QString& aInterfaceName)
+ {
+ TPtrC interfaceNamePtr(reinterpret_cast<const TUint16*>(aInterfaceName.utf16()));
+ HBufC* interfaceNamebuf = HBufC::New(interfaceNamePtr.Length());
+ interfaceNamebuf->Des().Copy(interfaceNamePtr);
+ TPckgBuf<TInt> lengthPckg(0);
+ TIpcArgs args(interfaceNamebuf, &lengthPckg, &iError);
+ SendReceive(EGetServiceNamesSizeRequest, args);
+
+ HBufC8* serviceNamesBuf = HBufC8::New(lengthPckg());
+ TPtr8 ptrToBuf(serviceNamesBuf->Des());
+ TIpcArgs args2(&ptrToBuf);
+ SendReceive(EGetServiceNamesRequest, args2);
+
+ QByteArray nameListByteArray((const char*)ptrToBuf.Ptr(), ptrToBuf.Length());
+ QDataStream out(nameListByteArray);
+ QStringList nameList;
+ out >> nameList;
+
+ delete interfaceNamebuf;
+ delete serviceNamesBuf;
+
+ return nameList;
+ }
+
+QServiceInterfaceDescriptor RDatabaseManagerSession::InterfaceDefault(const QString& aInterfaceName)
+ {
+ TPtrC interfaceNamePtr(reinterpret_cast<const TUint16*>(aInterfaceName.utf16()));
+ HBufC* interfaceNameBuf = HBufC::New(interfaceNamePtr.Length());
+ interfaceNameBuf->Des().Copy(interfaceNamePtr);
+ TPckgBuf<TInt> lengthPckg(0);
+ TIpcArgs args(interfaceNameBuf, &lengthPckg, &iError);
+ SendReceive(EInterfaceDefaultSizeRequest, args);
+
+ HBufC8* interfaceDescriptorBuf = HBufC8::New(lengthPckg());
+ TPtr8 ptrToBuf(interfaceDescriptorBuf->Des());
+ TIpcArgs args2(&ptrToBuf);
+ SendReceive(EInterfaceDefaultRequest, args2);
+
+ QByteArray interfaceDescriptorByteArray((const char*)interfaceDescriptorBuf->Ptr(), interfaceDescriptorBuf->Length());
+ QDataStream out(interfaceDescriptorByteArray);
+ QServiceInterfaceDescriptor interfaceDescriptor;
+ out >> interfaceDescriptor;
+
+ delete interfaceNameBuf;
+ delete interfaceDescriptorBuf;
+
+ return interfaceDescriptor;
+ }
+
+bool RDatabaseManagerSession::SetInterfaceDefault(const QString &aServiceName, const QString &aInterfaceName)
+ {
+ TPtrC serviceNamePtr(reinterpret_cast<const TUint16*>(aServiceName.utf16()));
+ TPtrC interfaceNamePtr(reinterpret_cast<const TUint16*>(aInterfaceName.utf16()));
+ TIpcArgs args(&serviceNamePtr, &interfaceNamePtr, &iError);
+ SendReceive(ESetInterfaceDefault, args);
+
+ return (iError() == DBError::NoError);
+ }
+
+bool RDatabaseManagerSession::SetInterfaceDefault(const QServiceInterfaceDescriptor &aInterface)
+ {
+ QByteArray interfaceByteArray;
+ QDataStream in(&interfaceByteArray, QIODevice::WriteOnly);
+ in.setVersion(QDataStream::Qt_4_6);
+ in << aInterface;
+ TPtrC8 ptr8((TUint8 *)(interfaceByteArray.constData()), interfaceByteArray.size());
+ TIpcArgs args(&ptr8, &iError);
+ SendReceive(ESetInterfaceDefault2, args);
+
+ return (iError() == DBError::NoError);
+ }
+
+DBError RDatabaseManagerSession::LastError()
+ {
+ DBError error;
+ error.setError((DBError::ErrorCode)iError());
+ return error;
+ }
+
+void RDatabaseManagerSession::SetChangeNotificationsEnabled(bool aEnabled)
+ {
+ TIpcArgs args((aEnabled ? 1 : 0), &iError);
+ SendReceive(ESetChangeNotificationsEnabledRequest, args);
+ }
+
+void RDatabaseManagerSession::NotifyServiceSignal(TRequestStatus& aStatus)
+ {
+ iArgs.Set(0, &iServiceName);
+ iArgs.Set(1, &iState);
+ iArgs.Set(2, &iError);
+ SendReceive(ENotifyServiceSignalRequest, iArgs, aStatus);
+ }
+
+void RDatabaseManagerSession::CancelNotifyServiceSignal() const
+ {
+ SendReceive(ECancelNotifyServiceSignalRequest, TIpcArgs(NULL));
+ }
+
+#include "moc_databasemanager_symbian_p.cpp"
+
+QTM_END_NAMESPACE
+
+#endif //defined(__WINS__) && !defined(SYMBIAN_EMULATOR_SUPPORTS_PERPROCESS_WSD)