--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qtmobility/src/serviceframework/databasemanager_s60.cpp Fri Apr 16 15:51:22 2010 +0300
@@ -0,0 +1,546 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "databasemanager_s60_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()
+{
+ int err = iSession.Connect();
+
+ int i = 0;
+ while (err != KErrNone) {
+ if (i > 10)
+ qt_symbian_throwIfError(err);
+
+ User::After(50);
+ err = iSession.Connect();
+ i++;
+ }
+
+ 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);
+}
+
+/*
+ \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()
+ {
+#ifdef __WINS__
+ iServerThread = NULL;
+#endif
+ }
+
+TVersion RDatabaseManagerSession::Version() const
+ {
+ return TVersion(KServerMajorVersionNumber, KServerMinorVersionNumber, KServerBuildVersionNumber);
+ }
+
+TInt RDatabaseManagerSession::Connect()
+ {
+ TInt err = StartServer();
+ if (err == KErrNone)
+ {
+ err = CreateSession(KDatabaseManagerServerName, Version()); //Default message slots
+ }
+ return err;
+ }
+
+TInt RDatabaseManagerSession::StartServer()
+ {
+ TInt ret = KErrNone;
+ TFindServer findServer(KDatabaseManagerServerName);
+ TFullName name;
+
+ if (findServer.Next(name) != KErrNone)
+ {
+#ifdef __WINS__
+ iServerThread = new CDatabaseManagerServerThread();
+ iServerThread->start();
+ iServerThread->wait(1);
+#else
+ TRequestStatus status;
+ RProcess dbServer;
+ ret = dbServer.Create(KDatabaseManagerServerName, 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();
+#endif
+ }
+
+ 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);
+ }
+
+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));
+ }
+
+
+#ifdef __WINS__
+QTM_END_NAMESPACE
+ #include "databasemanagerserver.h"
+QTM_BEGIN_NAMESPACE
+
+ CDatabaseManagerServerThread::CDatabaseManagerServerThread()
+ {
+ }
+
+ void CDatabaseManagerServerThread::run()
+ {
+ CDatabaseManagerServer *dbManagerServer = new CDatabaseManagerServer();
+ __ASSERT_ALWAYS(dbManagerServer != NULL, CDatabaseManagerServer::PanicServer(ESrvCreateServer));
+
+ TInt err = dbManagerServer->Start(KDatabaseManagerServerName);
+ if (err != KErrNone)
+ {
+ CDatabaseManagerServer::PanicServer(ESvrStartServer);
+ }
+ RThread::Rendezvous(KErrNone);
+
+ exec();
+
+ delete dbManagerServer;
+ }
+#endif
+
+#include "moc_databasemanager_s60_p.cpp"
+
+QTM_END_NAMESPACE