diff -r 000000000000 -r 876b1a06bc25 src/serviceframework/databasemanagerserver_symbian/databasemanagersession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/serviceframework/databasemanagerserver_symbian/databasemanagersession.cpp Wed Aug 25 15:49:42 2010 +0300 @@ -0,0 +1,642 @@ +/**************************************************************************** +** +** 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$ +** 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 "clientservercommon.h" +#include "databasemanagersession.h" +#include "databasemanagerserver.pan" +#include "databasemanagersignalhandler.h" +#include "servicedatabase_p.h" +#include "databasemanagerserver.h" + +#include + +QTM_BEGIN_NAMESPACE + +bool lessThan(const QServiceInterfaceDescriptor &d1, + const QServiceInterfaceDescriptor &d2) + { + return (d1.majorVersion() < d2.majorVersion()) + || ( d1.majorVersion() == d2.majorVersion() + && d1.minorVersion() < d2.minorVersion()); + } + +CDatabaseManagerServerSession* CDatabaseManagerServerSession::NewL(CDatabaseManagerServer& aServer) + { + CDatabaseManagerServerSession* self = CDatabaseManagerServerSession::NewLC(aServer); + CleanupStack::Pop(self); + return self; + } + +CDatabaseManagerServerSession* CDatabaseManagerServerSession::NewLC(CDatabaseManagerServer& aServer) + { + CDatabaseManagerServerSession* self = new (ELeave) CDatabaseManagerServerSession(aServer); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CDatabaseManagerServerSession::ConstructL() + { + iDb = new ServiceDatabase(); + initDbPath(); + iDatabaseManagerSignalHandler = new DatabaseManagerSignalHandler(*this); + } + +CDatabaseManagerServerSession::CDatabaseManagerServerSession(CDatabaseManagerServer& aServer) + : iServer(aServer), + iDatabaseManagerSignalHandler(NULL), + iDb(NULL), + m_watcher(NULL) + { + iServer.IncreaseSessions(); + } + +CDatabaseManagerServerSession::~CDatabaseManagerServerSession() + { + delete iDatabaseManagerSignalHandler; + delete iDb; + delete iByteArray; + delete m_watcher; + iServer.DecreaseSessions(); + } + +void CDatabaseManagerServerSession::ServiceL(const RMessage2& aMessage) + { + if (aMessage.Function() == ENotifyServiceSignalRequest) + { + NotifyServiceSignal(aMessage); + } + else + { + TRAPD(err, DispatchMessageL(aMessage)); + aMessage.Complete(err); + } + } + +void CDatabaseManagerServerSession::DispatchMessageL(const RMessage2& aMessage) + { + switch (aMessage.Function()) + { + case ERegisterServiceRequest: + User::LeaveIfError(RegisterServiceL(aMessage)); + break; + case EUnregisterServiceRequest: + User::LeaveIfError(UnregisterServiceL(aMessage)); + break; + case EServiceInitializedRequest: + User::LeaveIfError(ServiceInitializedL(aMessage)); + break; + case EGetInterfacesRequest: + User::LeaveIfError(InterfacesL(aMessage)); + break; + case EGetInterfacesSizeRequest: + User::LeaveIfError(InterfacesSizeL(aMessage)); + break; + case EGetServiceNamesRequest: + User::LeaveIfError(ServiceNamesL(aMessage)); + break; + case EGetServiceNamesSizeRequest: + User::LeaveIfError(ServiceNamesSizeL(aMessage)); + break; + case EInterfaceDefaultRequest: + User::LeaveIfError(InterfaceDefaultL(aMessage)); + break; + case ESetInterfaceDefault: + User::LeaveIfError(SetInterfaceDefaultL(aMessage)); + break; + case ESetInterfaceDefault2: + User::LeaveIfError(SetInterfaceDefault2L(aMessage)); + break; + case ESetChangeNotificationsEnabledRequest: + SetChangeNotificationsEnabled(aMessage); + break; + case EInterfaceDefaultSizeRequest: + User::LeaveIfError(InterfaceDefaultSize(aMessage)); + break; + case ECancelNotifyServiceSignalRequest: + User::LeaveIfError(CancelNotifyServiceSignal(aMessage)); + break; + default: + aMessage.Panic(KUnknownOpCode, KErrNotSupported); + break; + } + } + +TInt CDatabaseManagerServerSession::InterfaceDefaultSize(const RMessage2& aMessage) + { + TInt ret; + HBufC* defaultInterfaceBuf = HBufC::New(aMessage.GetDesLength(0)); + if (!defaultInterfaceBuf) + return KErrNoMemory; + + TPtr ptrToBuf(defaultInterfaceBuf->Des()); + TRAP(ret, aMessage.ReadL(0, ptrToBuf)); + + + QString interfaceName = QString::fromUtf16(ptrToBuf.Ptr(), ptrToBuf.Length()); + QServiceInterfaceDescriptor descriptor; + descriptor = iDb->interfaceDefault(interfaceName); + + iByteArray = new QByteArray(); + + QDataStream in(iByteArray, QIODevice::WriteOnly); + in.setVersion(QDataStream::Qt_4_6); + in << descriptor; + + TPckgBuf size(iByteArray->size()); + + aMessage.Write(1, size); + aMessage.Write(2, LastErrorCode()); + delete defaultInterfaceBuf; + + return ret; + } + +TInt CDatabaseManagerServerSession::InterfaceDefaultL(const RMessage2& aMessage) + { + TPtrC8 defaultInterfacePtr8((TUint8*)(iByteArray->constData()), iByteArray->size()); + aMessage.Write(0, defaultInterfacePtr8); + delete iByteArray; + iByteArray = NULL; + + return 0; + } + +void CDatabaseManagerServerSession::NotifyServiceSignal(const RMessage2& aMessage) + { + iMsg = aMessage; + iWaitingAsyncRequest = ETrue; + } + +TInt CDatabaseManagerServerSession::CancelNotifyServiceSignal(const RMessage2& /*aMessage*/) + { + if (iWaitingAsyncRequest) + { + iMsg.Complete(KErrCancel); + iWaitingAsyncRequest = EFalse; + } + + return KErrNone; + } + +TInt CDatabaseManagerServerSession::RegisterServiceL(const RMessage2& aMessage) + { + QString securityToken; + + TVendorId vendorId = aMessage.VendorId(); + if (vendorId != 0) + { + securityToken = QString::number(vendorId); + } + else + { + securityToken = QString::number(aMessage.SecureId().iId); + } + + TInt ret; + HBufC8* serviceMetaDataBuf8 = HBufC8::New(aMessage.GetDesLength(0)); + if (!serviceMetaDataBuf8) + return KErrNoMemory; + + TPtr8 ptrToBuf(serviceMetaDataBuf8->Des()); + TRAP(ret, aMessage.ReadL(0, ptrToBuf)); + if (ret != KErrNone) + { + iDb->lastError().setError(DBError::UnknownError); + aMessage.Write(1, LastErrorCode()); + delete serviceMetaDataBuf8; + return ret; + } + + QByteArray byteArray((const char*)ptrToBuf.Ptr(), ptrToBuf.Length()); + QDataStream out(byteArray); + ServiceMetaDataResults results; + out >> results; + + iDb->registerService(results, securityToken); + + aMessage.Write(1, LastErrorCode()); + + delete serviceMetaDataBuf8; + + return ret; + } + +TInt CDatabaseManagerServerSession::UnregisterServiceL(const RMessage2& aMessage) + { + QString securityToken; + + TVendorId vendorId = aMessage.VendorId(); + if (vendorId != 0) + { + securityToken = QString::number(vendorId); + } + else + { + securityToken = QString::number(aMessage.SecureId().iId); + } + + TInt ret; + HBufC* serviceNameBuf = HBufC::New(aMessage.GetDesLength(0)); + if (!serviceNameBuf) + return KErrNoMemory; + + TPtr ptrToBuf(serviceNameBuf->Des()); + TRAP(ret, aMessage.ReadL(0, ptrToBuf)); + if (ret != KErrNone) + { + iDb->lastError().setError(DBError::UnknownError); + aMessage.Write(1, LastErrorCode()); + delete serviceNameBuf; + return ret; + } + + QString serviceName = QString::fromUtf16(ptrToBuf.Ptr(), ptrToBuf.Length()); + iDb->unregisterService(serviceName, securityToken); + + aMessage.Write(1, LastErrorCode()); + delete serviceNameBuf; + + return ret; + } + +TInt CDatabaseManagerServerSession::ServiceInitializedL(const RMessage2& aMessage) + { + QString securityToken; + + TVendorId vendorId = aMessage.VendorId(); + if (vendorId != 0) + { + securityToken = QString::number(vendorId); + } + else + { + securityToken = QString::number(aMessage.SecureId().iId); + } + + TInt ret; + HBufC* serviceNameBuf = HBufC::New(aMessage.GetDesLength(0)); + if (!serviceNameBuf) + return KErrNoMemory; + + TPtr ptrToBuf(serviceNameBuf->Des()); + TRAP(ret, aMessage.ReadL(0, ptrToBuf)); + if (ret != KErrNone) + { + iDb->lastError().setError(DBError::UnknownError); + aMessage.Write(1, LastErrorCode()); + delete serviceNameBuf; + return ret; + } + + QString serviceName = QString::fromUtf16(ptrToBuf.Ptr(), ptrToBuf.Length()); + iDb->serviceInitialized(serviceName, securityToken); + + aMessage.Write(1, LastErrorCode()); + delete serviceNameBuf; + + return ret; + } + +TInt CDatabaseManagerServerSession::InterfacesSizeL(const RMessage2& aMessage) + { + TInt ret; + HBufC8* buf = HBufC8::New(aMessage.GetDesLength(0)); + if (!buf) + return KErrNoMemory; + + TPtr8 ptrToBuf(buf->Des()); + TRAP(ret, aMessage.ReadL(0, ptrToBuf)); + if (ret != KErrNone) + { + iDb->lastError().setError(DBError::UnknownError); + aMessage.Write(2, LastErrorCode()); + delete buf; + return ret; + } + + QByteArray byteArray((const char*)ptrToBuf.Ptr(), ptrToBuf.Length()); + QDataStream out(byteArray); + QServiceFilter filter; + out >> filter; + + QList interfaces = iDb->getInterfaces(filter); + iByteArray = new QByteArray(); + + QDataStream in(iByteArray, QIODevice::WriteOnly); + in.setVersion(QDataStream::Qt_4_6); + in << interfaces; + + TPckgBuf size(iByteArray->size()); + aMessage.Write(1, size); + aMessage.Write(2, LastErrorCode()); + + delete buf; + return ret; + } + +TInt CDatabaseManagerServerSession::InterfacesL(const RMessage2& aMessage) + { + TPtrC8 interfacesPtr8((TUint8*)(iByteArray->constData()), iByteArray->size()); + aMessage.Write(0, interfacesPtr8); + delete iByteArray; + iByteArray = NULL; + + return 0; + } + +TInt CDatabaseManagerServerSession::ServiceNamesSizeL(const RMessage2& aMessage) + { + TInt ret; + HBufC* serviceNamesBuf = HBufC::New(aMessage.GetDesLength(0)); + if (!serviceNamesBuf) + return KErrNoMemory; + + TPtr ptrToBuf (serviceNamesBuf->Des()); + TRAP(ret, aMessage.ReadL(0, ptrToBuf)); + if (ret != KErrNone) + { + iDb->lastError().setError(DBError::UnknownError); + aMessage.Write(2, LastErrorCode()); + delete serviceNamesBuf; + return ret; + } + + QString interfaceName = QString::fromUtf16(ptrToBuf.Ptr(), ptrToBuf.Length()); + QStringList serviceNames = iDb->getServiceNames(interfaceName); + iByteArray = new QByteArray(); + + QDataStream in(iByteArray, QIODevice::WriteOnly); + in.setVersion(QDataStream::Qt_4_6); + in << serviceNames; + + TPckgBuf size(iByteArray->size()); + aMessage.Write(1, size); + aMessage.Write(2, LastErrorCode()); + delete serviceNamesBuf; + + return ret; + } + +TInt CDatabaseManagerServerSession::ServiceNamesL(const RMessage2& aMessage) + { + TPtrC8 ptr8((TUint8*)(iByteArray->constData()), iByteArray->size()); + aMessage.Write(0, ptr8); + delete iByteArray; + iByteArray = NULL; + + return 0; + } + +TInt CDatabaseManagerServerSession::SetInterfaceDefaultL(const RMessage2& aMessage) + { + TInt ret; + HBufC* serviceNameBuf = HBufC::New(aMessage.GetDesLength(0)); + HBufC* interfaceNameBuf = HBufC::New(aMessage.GetDesLength(1)); + if (!serviceNameBuf || !interfaceNameBuf) + return KErrNoMemory; + + TPtr ptrToBuf(serviceNameBuf->Des()); + TPtr ptrToBuf2(interfaceNameBuf->Des()); + + TRAP(ret, aMessage.ReadL(0, ptrToBuf)); + TRAPD(ret2, aMessage.ReadL(1, ptrToBuf2)); + if (ret != KErrNone || ret2 != KErrNone) + { + iDb->lastError().setError(DBError::UnknownError); + aMessage.Write(2, LastErrorCode()); + delete serviceNameBuf; + delete interfaceNameBuf; + return (ret == KErrNone) ? ret2 : ret; + } + + QString serviceName = QString::fromUtf16(ptrToBuf.Ptr(), ptrToBuf.Length()); + QString interfaceName = QString::fromUtf16(ptrToBuf2.Ptr(), ptrToBuf2.Length()); + + QList descriptors; + QServiceFilter filter; + filter.setServiceName(serviceName); + filter.setInterface(interfaceName); + // Nothing should be returned, because we are checking on nonexistent service + descriptors = iDb->getInterfaces(filter); + + //find the descriptor with the latest version + int latestIndex = 0; + for (int i = 1; i < descriptors.count(); ++i) { + if (lessThan(descriptors[latestIndex], descriptors[i])) + latestIndex = i; + } + + if (!descriptors.isEmpty()) { + iDb->setInterfaceDefault(descriptors[latestIndex]); + } + else { + aMessage.Write(2, TError(DBError::NotFound)); + delete serviceNameBuf; + delete interfaceNameBuf; + return KErrNotFound; + } + + aMessage.Write(2, LastErrorCode()); + delete serviceNameBuf; + delete interfaceNameBuf; + + return ret; + } + +TInt CDatabaseManagerServerSession::SetInterfaceDefault2L(const RMessage2& aMessage) + { + TInt ret; + HBufC8* interfaceBuf = HBufC8::New(aMessage.GetDesLength(0)); + if (!interfaceBuf) + return KErrNoMemory; + + TPtr8 ptrToBuf(interfaceBuf->Des()); + TRAP(ret, aMessage.ReadL(0, ptrToBuf)); + if (ret != KErrNone) + { + iDb->lastError().setError(DBError::UnknownError); + aMessage.Write(1, LastErrorCode()); + delete interfaceBuf; + return ret; + } + + QByteArray interfaceDescriptorByteArray((const char*)ptrToBuf.Ptr(), ptrToBuf.Length()); + QDataStream out(interfaceDescriptorByteArray); + QServiceInterfaceDescriptor interfaceDescriptor; + out >> interfaceDescriptor; + + iDb->setInterfaceDefault(interfaceDescriptor); + aMessage.Write(1, LastErrorCode()); + delete interfaceBuf; + + return ret; + } + +void CDatabaseManagerServerSession::SetChangeNotificationsEnabled(const RMessage2& aMessage) + { + if (!m_watcher) + { + m_watcher = new QFileSystemWatcher(QStringList() << iDb->databasePath()); + QObject::connect(m_watcher, SIGNAL(fileChanged(QString)), + iDatabaseManagerSignalHandler, SLOT(databaseChanged(QString))); + } + + + if (aMessage.Int0() == 1) // 1 == Notifications enabled + { + m_knownServices.clear(); + m_knownServices = iDb->getServiceNames(QString()); + } + else + { + m_watcher->removePath(iDb->databasePath()); + m_knownServices.clear(); + } + + aMessage.Write(1, LastErrorCode()); + } + +void CDatabaseManagerServerSession::databaseChanged(const QString &path) + { + QStringList currentServices = iDb->getServiceNames(QString()); + + if (currentServices == m_knownServices) + return; + + QStringList newServices; + for (int i=0; ilastError().code()); + } + +void CDatabaseManagerServerSession::ServiceAdded(const QString& aServiceName) + { + if (iWaitingAsyncRequest) + { + TPckgBuf state(0); + TPtrC str(reinterpret_cast(aServiceName.utf16())); + iMsg.Write(0, str); + iMsg.Write(1, state); + iMsg.Write(2, LastErrorCode()); + iMsg.Complete(ENotifySignalComplete); + iWaitingAsyncRequest = EFalse; + } + } + +void CDatabaseManagerServerSession::ServiceRemoved(const QString& aServiceName) + { + if (iWaitingAsyncRequest) + { + TPckgBuf state(1); + TPtrC str(reinterpret_cast(aServiceName.utf16())); + iMsg.Write(0, str); + iMsg.Write(1, state); + iMsg.Write(2, LastErrorCode()); + iMsg.Complete(ENotifySignalComplete); + iWaitingAsyncRequest = EFalse; + } + } + +void CDatabaseManagerServerSession::initDbPath() + { + QString dbIdentifier = "_system"; + ServiceDatabase *db = iDb; + QDir dir(QDir::toNativeSeparators(QCoreApplication::applicationDirPath())); + QString qtVersion(qVersion()); + qtVersion = qtVersion.left(qtVersion.size() -2); //strip off patch version + QString dbName = QString("QtServiceFramework_") + qtVersion + dbIdentifier + QLatin1String(".db"); + db->setDatabasePath(dir.path() + QDir::separator() + dbName); + + // check if database is copied from Z drive; also valid for emulator + QFile dbFile(iDb->databasePath()); + QFileInfo dbFileInfo(dbFile); + if (!dbFileInfo.exists()) { + // create folder first + if (!dbFileInfo.dir().exists()) + QDir::root().mkpath(dbFileInfo.path()); + // copy file from ROM + QFile romDb(QLatin1String("z:\\private\\2002ac7f\\") + dbFileInfo.fileName()); + if (romDb.open(QIODevice::ReadOnly) && dbFile.open(QFile::WriteOnly)) { + QByteArray data = romDb.readAll(); + dbFile.write(data); + dbFile.close(); + romDb.close(); + } + } + + openDb(); + } + +bool CDatabaseManagerServerSession::openDb() + { + if (iDb) { + if (iDb->isOpen()) { + return true; + } else { + return iDb->open(); + } + } + + return false; + } + +QTM_END_NAMESPACE + +// End of File