diff -r 5d007b20cfd0 -r cd2778e5acfe qthighway/xqserviceutil/src/xqservicemanager.cpp --- a/qthighway/xqserviceutil/src/xqservicemanager.cpp Tue Aug 31 16:02:37 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1051 +0,0 @@ -/* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Lesser General Public License as published by -* the Free Software Foundation, version 2.1 of the License. -* -* 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 Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public License -* along with this program. If not, -* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/". -* -* Description: -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "xqservicelog.h" -#include -#include "xqrequestutil.h" -#include "xqservicemanager.h" -#include "xqserviceipcconst.h" - -#include "xqservicemetadata/xqservicemetadata_p.h" -#include -#include "xqconversions.h" - - -#define TIMER_DELAY 3000 - -class CProcessInfo : public CActive - { - public: - static void AddProcessL(const TUid& appUid, RProcess& appProcess); - static void EnsureProcessCanStartL(const TUid& appUid); - - protected: - CProcessInfo(const TUid& appUid); - ~CProcessInfo(); - void ConstructL(RProcess& appProcess); - void DoCancel(); - void RunL(); - - protected: - class ProcessInfoMap - { - public: - ~ProcessInfoMap() - { - foreach (CProcessInfo* info, map.values()) - delete info; - } - QHash map; - }; - - static ProcessInfoMap iProcessInfoMap; - const TUid iAppUid; - }; - - - -CProcessInfo::ProcessInfoMap CProcessInfo::iProcessInfoMap; - -CProcessInfo::CProcessInfo(const TUid& appUid): - CActive(CActive::EPriorityStandard), - iAppUid(appUid) -{ - XQSERVICE_DEBUG_PRINT("CProcessInfo::CProcessInfo"); - - CActiveScheduler::Add(this); -} - -CProcessInfo::~CProcessInfo() -{ - XQSERVICE_DEBUG_PRINT("CProcessInfo::~CProcessInfo"); - - // Cancel asynch request, normally it should be done in DoCancel() - // but we dont wont to cancel request when we cancel active object - User::CancelMiscNotifier(iStatus); - - Cancel(); -} - -void CProcessInfo::AddProcessL(const TUid& appUid, RProcess& appProcess) -{ - XQSERVICE_DEBUG_PRINT("CProcessInfo::AddProcessL"); - - CProcessInfo* self = new(ELeave) CProcessInfo(appUid); - CleanupStack::PushL(self); - self->ConstructL(appProcess); - CleanupStack::Pop(self); -} - -void CProcessInfo::EnsureProcessCanStartL(const TUid& appUid) -{ - XQSERVICE_DEBUG_PRINT("CProcessInfo::EnsureProcessCanStartL"); - - CProcessInfo* previousProcess = iProcessInfoMap.map[appUid.iUid]; - if (previousProcess) { - previousProcess->Cancel(); - - // Timer is for ensure that wait will end. - // Maybe there is possibility that destroing process notification could be lost. - RTimer securityTimer; - securityTimer.CreateLocal(); - CleanupClosePushL(securityTimer); - - TRequestStatus timerStatus; - securityTimer.After(timerStatus, TIMER_DELAY); - User::WaitForRequest(previousProcess->iStatus, timerStatus); - - CleanupStack::PopAndDestroy(); - delete previousProcess; - iProcessInfoMap.map.remove(appUid.iUid); - } -} - -void CProcessInfo::RunL() -{ - XQSERVICE_DEBUG_PRINT("CProcessInfo::RunL"); - - iProcessInfoMap.map.remove(iAppUid.iUid); - delete this; -} - -void CProcessInfo::ConstructL(RProcess& appProcess) -{ - XQSERVICE_DEBUG_PRINT("CProcessInfo::ConstructL"); - - SetActive(); - - EnsureProcessCanStartL(iAppUid); - iProcessInfoMap.map.insert(iAppUid.iUid, this); - appProcess.NotifyDestruction(iStatus); -} - -void CProcessInfo::DoCancel() -{ - XQSERVICE_DEBUG_PRINT("CProcessInfo::DoCancel"); - - // Cancel asynch request, normally it should be done in DoCancel() - // but we dont wont to cancel request when we cancel active object. - // Cancel asynch request is in ~CProcessInfo(). -} - -/*! - \class XQServiceManagerPrivate - \brief Private implementation of the XQServiceManager. -*/ -class XQServiceManagerPrivate - { - public: - XQServiceManagerPrivate(); - ~XQServiceManagerPrivate(); - - enum matchMode - { - MatchInterfaceName, - MatchServiceAndInterfaceName - }; - - int StartServer(const QString& aService, bool embedded, int& applicationUid, quint64& processId, - XQRequestUtil *util); - TInt Discover(const QString& aService,TUid& aAppUid, QList& interfaces, int matchMode, - bool findFirst=false); - int LatestError() const {return iLatestError;}; - bool IsRunning(const XQAiwInterfaceDescriptor& implementation) const; - - private: - void StartServerL(const TUid& uid, bool embedded, TUint64& processId, XQRequestUtil *util); - TInt Discover(const TDesC& aService,TUid& aAppUid, QList& interfaces, int matchMode, - bool findFirst=false); - TInt Discover1(const TDesC& aService,TUid& aAppUid, QList& interfaces, int matchMode, - bool findFirst=false); - TInt Discover2(const TDesC& aService,TUid& aAppUid, QList& interfaces, int matchMode, - bool findFirst=false); - CApaAppServiceInfoArray* AvailableServiceImplementations1L(); - CApaAppServiceInfoArray* AvailableServiceImplementations2L(); - TUint64 getAppPid(const TUid& aAppUid); - int doMapErrors(TInt aError); - - TVersion iVersion; - TApaAppInfo iAppInfo; - int iLatestError; - RApaLsSession iApaSession; - XQAiwInterfaceDescriptor iImplDescriptor; - }; - -/*! - \class XQServiceManager - \brief Discovery and service startup. -*/ - -/*! - Constructor. -*/ -XQServiceManager::XQServiceManager() -{ - XQSERVICE_DEBUG_PRINT("XQServiceManager::XQServiceManager"); - d = new XQServiceManagerPrivate(); -} - -/*! - Destructor. -*/ -XQServiceManager::~XQServiceManager() -{ - XQSERVICE_DEBUG_PRINT("XQServiceManager::~XQServiceManager"); - delete d; -} - -/*! - Starts service - \param service The full name of service (servicename + interfacename). - \param embedded Start in embedded mode. - \param applicationUid Returned applicatiion. - \param threadId Returned process id of the application. - \return Error code if error occured, 0 otherwise. -*/ -int XQServiceManager::startServer(const QString& service, bool embedded, int& applicationUid, quint64& threadId) -{ - XQSERVICE_DEBUG_PRINT("XQServiceManager::startServer(1)"); - return startServer(service,embedded,applicationUid,threadId,NULL); -} - -/*! - Starts service - \param service The full name of service (servicename + interfacename). - \param embedded Start in embedded mode. - \param applicationUid Returned applicatiion. - \param threadId Returned process id of the application. - \param userData Additional user data. - \return Error code if error occured, 0 otherwise. -*/ -int XQServiceManager::startServer(const QString& service, bool embedded, int& applicationUid, quint64& threadId, - const void *userData) -{ - XQSERVICE_DEBUG_PRINT("XQServiceManager::startServer(2)"); - - // The "XQServiceRequest::send(QVariant& retData)" function passed the utility as user data - // the IPC layer. Could be NULL if no descriptor was given upon creating the request. - // The util data is known to be writeable (though passed as const userData) - XQRequestUtil *util = static_cast((void *)userData); - if (util == 0) - { - // Something is badly wrong as this should be always avaible - return XQService::EMgrInternalError; - } - - return d->StartServer(service,embedded,applicationUid,threadId, util); -} - - -/*! - Finds implementations for the given interface. - \param interfaceName Interfacename to match. - \return List of implementations. -*/ -QList XQServiceManager::findInterfaces ( const QString &interfaceName ) const - { - XQSERVICE_DEBUG_PRINT("XQServiceManager::findInterfaces 1"); - QList interfaces; - TUid appUid; - interfaces.clear(); - TInt error=d->Discover(interfaceName, appUid, interfaces, XQServiceManagerPrivate::MatchInterfaceName); - return interfaces; - } - -/*! - Finds implementations for the given interface implemented by given service. - \param serviceName Service name. - \param interfaceName Interfacename to match. - \return List of implementations. -*/ -QList XQServiceManager::findInterfaces ( const QString &serviceName, const QString &interfaceName ) const -{ - XQSERVICE_DEBUG_PRINT("XQServiceManager::findInterfaces 2"); - QList interfaces; - TUid appUid; - interfaces.clear(); - TInt error=d->Discover(serviceName + "." + interfaceName, appUid, interfaces, - XQServiceManagerPrivate::MatchServiceAndInterfaceName); - return interfaces; -} - - -/*! - Finds the first implementation for the given interface name. - \param interfaceName Interfacename to match. - \return List of implementations. -*/ -QList XQServiceManager::findFirstInterface ( const QString &interfaceName ) const -{ - XQSERVICE_DEBUG_PRINT("XQServiceManager::findFirstInterface 1"); - QList interfaces; - TUid appUid; - interfaces.clear(); - TInt error=d->Discover(interfaceName, appUid, interfaces, XQServiceManagerPrivate::MatchInterfaceName, true); - return interfaces; -} - -/*! - Finds the first implementation for the given service + interface names. - \param serviceName Service name. - \param interfaceName Interfacename to match. - \return List of implementations. -*/ -QList XQServiceManager::findFirstInterface ( const QString &serviceName, const QString &interfaceName ) const -{ - XQSERVICE_DEBUG_PRINT("XQServiceManager::findFirstInterface 2"); - QList interfaces; - TUid appUid; - interfaces.clear(); - // Catenate to get full name - TInt error=d->Discover(serviceName + "." + interfaceName, appUid, interfaces, - XQServiceManagerPrivate::MatchServiceAndInterfaceName, true); - return interfaces; -} - - -/*! - Gets the latest error occured. - \return Latest error code as integer value. -*/ -int XQServiceManager::latestError() const -{ - return d->LatestError(); -} - -/*! - Checks if the given \a implmentation is running. - \param implementation Implementation to be checked. - \return true if given \a implementation is running, false otherwise. -*/ -bool XQServiceManager::isRunning(const XQAiwInterfaceDescriptor& implementation) const -{ - XQSERVICE_DEBUG_PRINT("XQServiceManager::isRunning"); - return d->IsRunning(implementation); -} - -// ====== Private part ============== - -XQServiceManagerPrivate::XQServiceManagerPrivate() -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::XQServiceManagerPrivate"); - iLatestError = 0; - iApaSession.Connect(); -} - -XQServiceManagerPrivate::~XQServiceManagerPrivate() -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::~XQServiceManagerPrivate"); - iApaSession.Close(); -}; - -// aService is here the full name (service + interface) -int XQServiceManagerPrivate::StartServer(const QString& aService, bool embedded, int& applicationUid, quint64& processId, - XQRequestUtil *util) -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::startServer(2)"); - XQSERVICE_DEBUG_PRINT("aService: %s", qPrintable(aService)); - - TUid appUid; - appUid.iUid=0; - - TInt error = KErrNone; - QList interfaces; - TPtrC serverName( reinterpret_cast(aService.utf16()) ); - if (util->mDescriptor.isValid()) - { - iImplDescriptor=util->mDescriptor; // Descriptor given by caller - appUid.iUid = util->mDescriptor.property(XQAiwInterfaceDescriptor::ImplementationId).toInt(); - XQSERVICE_DEBUG_PRINT("ApplicationUid from descriptor: %x", appUid.iUid); - } - - // Need to discover service first if descriptor did not contained valid UID - // Otherwise, go directly starting the service server - if (appUid.iUid == 0) - { - // Find the first implementation - error = Discover(serverName,appUid,interfaces, XQServiceManagerPrivate::MatchServiceAndInterfaceName, true); - if (interfaces.count()) - { - iImplDescriptor=interfaces[0]; // Descriptor search upon start - } - } - if (error) - { - return doMapErrors(error); - } - - TRAP(error, StartServerL(appUid,embedded,processId, util)); - applicationUid = appUid.iUid ; - - XQSERVICE_DEBUG_PRINT("ApplicationUid: %x, processId: %d", applicationUid, processId); - XQSERVICE_DEBUG_PRINT("error: %d", error); - return doMapErrors(error); -} - -void XQServiceManagerPrivate::StartServerL(const TUid& uid, bool embedded, TUint64& processId, - XQRequestUtil *util) -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::StartServerL"); - Q_UNUSED(embedded); // Not used any more. XQRequestUtil applied instead - - bool toBackground = false; - // Apply the utility's option for embedding instead - bool embed = util->mInfo.isEmbedded(); - toBackground = util->mInfo.isBackground(); - - XQSERVICE_DEBUG_PRINT("\tembedded got from utility=%d", embed); - XQSERVICE_DEBUG_PRINT("\tbackground got from utility=%d", toBackground); - - // retrieve application information - User::LeaveIfError( iApaSession.GetAppInfo( iAppInfo, uid ) ); - - TApaAppCapabilityBuf caps; - User::LeaveIfError(iApaSession.GetAppCapability(caps, uid)); - if (!toBackground) - { - // If service wants to be launched to background.. respect it - toBackground = caps().iLaunchInBackground; - XQSERVICE_DEBUG_PRINT("\tbackground from apparch=%d", toBackground); - } - - // Consistency check - if (embed && toBackground) - { - User::Leave(KErrArgument); - } - - /* - // Using the "iAppInfo.iCaption" is wrong as the channel name (full servicename) shall be used: - // e.g. tester's "com.nokia.servicesd.serviceapp.Dialer" or - // "com.nokia.servicesd.serviceapp.Dialer.PROCESS-ID" in case of embedded launch - // Anyway, this is not needed as the "XQServiceIpcClient::connectToServer()" takes care of the checking logic - // earlier (the "startServer" logic will be applied only when needed) - TFindServer find( iAppInfo.iCaption ); - TFullName fullName; - TInt err = find.Next( fullName ); - XQSERVICE_DEBUG_PRINT("err: %d", err); - */ - TInt err = KErrNotFound; // Assume not found - if ( err != KErrNone ) - { - CApaCommandLine* cmdLine = CApaCommandLine::NewLC(); - cmdLine->SetExecutableNameL( iAppInfo.iFullName ); - TApaCommand aLaunchCommand = toBackground ? EApaCommandBackground : EApaCommandRun; - cmdLine->SetCommandL(aLaunchCommand); - - // just use the Secure ID as server differentiator - //cmdLine->SetServerRequiredL( uid.iUid ); - RProcess client; - cmdLine->SetServerRequiredL(client.Id().Id()); - if (embed) { - CCoeEnv* env= CCoeEnv::Static(); - if (env) // Could be NULL - { - RWindowGroup& wg = env->RootWin(); - wg.AllowProcessToCreateChildWindowGroups(iAppInfo.iUid); - TInt parentId = wg.Identifier(); - if (parentId) - { - // pass our window group ID to the embedded child process - cmdLine->SetParentWindowGroupID(parentId); - XQSERVICE_DEBUG_PRINT("\tParent ID %x set for %x (%x)", (int)parentId, iAppInfo.iUid, uid.iUid); - } - } - else - { - // Can not be embedded (non GUI client) - embed = false; - } - } - else { - CProcessInfo::EnsureProcessCanStartL(uid); - } - TRequestStatus requestStatusForRendezvous; - - // start application with command line parameters - //User::LeaveIfError( iApaSession.StartApp( *cmdLine, threadId, &requestStatusForRendezvous) ); - QString startupArgs = QString::fromLatin1(XQServiceUtils::StartupArgService); - if (embed) - { - startupArgs += (" " + QString::fromLatin1(XQServiceUtils::StartupArgEmbedded)); - } - - // - // Add interface name and operation (message) name to the command line as startup args. - // Usable in practise only for the embedded launch - // Can be used by service application to prepare the UI to the coming call. - // - QStringList l = util->mOperation.split("("); - QString oper = l.value(0); // // Pick only the function name and ignore parameters - - startupArgs += (" " + QString::fromLatin1(XQServiceUtils::StartupArgInterfaceName) + iImplDescriptor.interfaceName() ); - startupArgs += (" " + QString::fromLatin1(XQServiceUtils::StartupArgServiceName) + iImplDescriptor.serviceName() ); - startupArgs += (" " + QString::fromLatin1(XQServiceUtils::StartupArgOperationName) + oper); - - XQSERVICE_DEBUG_PRINT("\tStartupArgs:%s", qPrintable(startupArgs)); - TPtrC cmdLineArgs( reinterpret_cast(startupArgs.utf16()) ); - - RProcess newApp; - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Creating process"); - User::LeaveIfError(newApp.Create(iAppInfo.iFullName, cmdLineArgs)); - CleanupClosePushL(newApp); - - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Created process"); - cmdLine->SetProcessEnvironmentL(newApp); - TProcessId newAppId = newApp.Id(); - processId = newAppId.Id(); - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Rendezvous for %x", processId); - newApp.Rendezvous(requestStatusForRendezvous); // Asynchronous - newApp.Resume(); - - User::WaitForRequest( requestStatusForRendezvous ); // Make the rendezvouz - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Rendezvous done %d", requestStatusForRendezvous.Int()); - - if (!embed) { - CProcessInfo::AddProcessL(uid, newApp); - } - - User::LeaveIfError( requestStatusForRendezvous.Int()); - CleanupStack::PopAndDestroy(2,cmdLine); // newApp, cmdLine - - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Done"); - } - -} - - -TUint64 XQServiceManagerPrivate::getAppPid(const TUid& aAppUid) -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::getAppPid"); - TUint64 pid = 0; - // Get the current task - RWsSession ws; - if (ws.Connect()==KErrNone) { - XQSERVICE_DEBUG_PRINT("Connected to window server"); - TApaTaskList tasklist( ws ); - TApaTask task = tasklist.FindApp( aAppUid ); - if (task.Exists()) { - XQSERVICE_DEBUG_PRINT("Application found"); - pid=task.ThreadId().Id(); - } - } - return pid; -} - -CApaAppServiceInfoArray* XQServiceManagerPrivate::AvailableServiceImplementations1L() -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::AvailableServiceImplementations1L"); - // retrieve list of available services implementations from apparc - CApaAppServiceInfoArray* apaInfo = - iApaSession.GetServiceImplementationsLC(TUid::Uid(KXQServiceUid)); - CleanupStack::Pop( apaInfo ); - return apaInfo; -} - -CApaAppServiceInfoArray* XQServiceManagerPrivate::AvailableServiceImplementations2L() -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::AvailableServiceImplementations2L"); - // retrieve list of available services implementations from apparc - CApaAppServiceInfoArray* apaInfo = - iApaSession.GetServiceImplementationsLC(TUid::Uid(KXQServiceUid2)); - CleanupStack::Pop( apaInfo ); - return apaInfo; -} - -TInt XQServiceManagerPrivate::Discover(const QString& aService,TUid& aAppUid, QList& interfaces, - int matchMode, bool findFirst) - { - TPtrC serverName( reinterpret_cast(aService.utf16()) ); - TInt error=Discover(serverName, aAppUid, interfaces, matchMode, findFirst); - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover (1)"); - return error; - } - -TInt XQServiceManagerPrivate::Discover( const TDesC& aService, - TUid& aAppUid, QList& interfaces, - int matchMode, bool findFirst) - { - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover (2)"); - TInt discoverResult1 = KErrNotFound; - TInt discoverResult2 = KErrNotFound; - - // Discover first possible reg files with old format - discoverResult1 = Discover1(aService, aAppUid, interfaces, matchMode, findFirst); - // Discover then reg files with new format (add results) - discoverResult2 = Discover2(aService, aAppUid, interfaces, matchMode, findFirst); - - if (discoverResult1 == KErrNone || discoverResult2 == KErrNone) - { - // Results merged - return KErrNone; - } - else - { - return KErrNotFound; - } - } - -TInt XQServiceManagerPrivate::Discover1( const TDesC& aService, - TUid& aAppUid, QList& interfaces, - int matchMode, bool findFirst) - { - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover1"); - - CApaAppServiceInfoArray* apaInfo = NULL; - TInt error = KErrNone; - TRAP(error, apaInfo = AvailableServiceImplementations1L()); - XQSERVICE_DEBUG_PRINT("Discover status=%d", error); - if (error) - { - return error; // This is fatal as nothing found - } - TArray implArray( apaInfo->Array() ); - XQSERVICE_DEBUG_PRINT("implArray.Count(): %d", implArray.Count()); - if ( !implArray.Count() ) - { - delete apaInfo; - return KErrNotFound; // No services found - } - - TBool found( EFalse ); - QString serviceName = QString::fromUtf16(aService.Ptr(),aService.Length()); - XQSERVICE_DEBUG_PRINT("serviceName: %s", qPrintable(serviceName)); - TBool firstUidPicked(EFalse); - - for ( TInt ii = 0; ii < implArray.Count(); ii++ ) - { - - // - // Reset error for each check round - // - error = KErrNone; - - TUid uid = implArray[ii].Uid(); - XQSERVICE_DEBUG_PRINT("implArray[%d].UID=%x", ii, uid); - - RResourceReader res; - // read opaque data - TRAP(error,res.OpenL( implArray[ii].OpaqueData() ) ) - if ( error ) - { - XQSERVICE_DEBUG_PRINT("OpaqueData error: %d", error); - delete apaInfo; - apaInfo = NULL; - continue; // Next could be OK - } - - //the first WORD contains the number of elements in the resource - int count = 0; - TRAP(error,count = res.ReadInt16L()); - if ( error ) - { - XQSERVICE_DEBUG_PRINT("resource error1: %d", error); - res.Close(); - delete apaInfo; - apaInfo = NULL; - continue; // Next could be OK - } - QByteArray xmlConf ; - XQSERVICE_DEBUG_PRINT("resource line count: %d", count); - for (int i=0; i < count ; i++) - { - TPtrC16 xmlBuf; - TRAP(error, xmlBuf.Set( res.ReadTPtrC16L() )); - if (error) - { - XQSERVICE_DEBUG_PRINT("resource error2: %d", error); - res.Close(); - delete apaInfo; - apaInfo = NULL; - break; - } - else - { - QString str=QString::fromUtf16(xmlBuf.Ptr(),xmlBuf.Length()); - XQSERVICE_DEBUG_PRINT("resource str: %s", qPrintable(str)); - xmlConf.append(str.toAscii()); - } - } - - // If we stop loop for the first resource error, - // it will hit cases where same interface has been implemented by multiple services - // So go on checking all the resource files - if (error) - { - continue; // Next could be OK - } - - XQSERVICE_DEBUG_PRINT("resource data: %s", xmlConf.constData()); - QBuffer buf(&xmlConf); - ServiceMetaData* metaData = new ServiceMetaData(&buf); - if (metaData->extractMetadata()) - { - ServiceMetaDataResults results=metaData->parseResults(); - // interfaces = results.interfaces; // return value set here ???!! - - // Go through all interfaces and pick the UI for the first matching one. - // THIS NEED TO BE FIXED IF SOMEONE WANTS DEDICATED IMPLEMENTATION - // Fill in the implementationId for all interfaces - foreach (XQAiwInterfaceDescriptor interface,results.interfaces) - { - QString sn; - QString snDeprecated; - if (results.version == ServiceMetaDataResults::VERSION_1) - { - // Old version of the XML format. The parser took care of adaptation - // discovery-name = service-name + interface name - XQSERVICE_DEBUG_PRINT("version 1"); - } - else - { - // discovery-name = interface name - XQSERVICE_DEBUG_PRINT("version 2"); - } - - // Deprecated service name, if any - QString deprecatedServiceName = interface.customProperty("deprecatedsn"); - bool deprNameExists = !deprecatedServiceName.isEmpty(); - if (deprNameExists) - { - XQSERVICE_DEBUG_PRINT("deprecatedServiceName: %s", qPrintable(deprecatedServiceName)); - } - - // This is the name used in match - // TODO: Version handling support: Take the latest version if multiple matches - switch (matchMode) - { - case MatchInterfaceName : - sn = interface.interfaceName(); - break; - case MatchServiceAndInterfaceName : - sn =interface.serviceName() + "." + interface.interfaceName(); - snDeprecated = deprecatedServiceName + "." + interface.interfaceName(); - break; - default: - sn = interface.interfaceName(); - break; - } - - XQSERVICE_DEBUG_PRINT("compare name is: %s", qPrintable(sn)); - XQSERVICE_DEBUG_PRINT("requested name: %s", qPrintable(serviceName)); - if ((!serviceName.compare(sn,Qt::CaseInsensitive)) || - (deprNameExists && !serviceName.compare(snDeprecated,Qt::CaseInsensitive))) - { - TUid appUid = implArray[ii].Uid(); - if (!firstUidPicked) - { - aAppUid = appUid; - firstUidPicked = ETrue; - XQSERVICE_DEBUG_PRINT("First service found UID3=%x", appUid.iUid); - } - XQSERVICE_DEBUG_PRINT("Service found UID3=%x", appUid.iUid); - // Add impl. UID to interface - interface.setProperty(XQAiwInterfaceDescriptor::ImplementationId, (int)appUid.iUid); - found = ETrue; - - // Add the matched interface to result set - interfaces.append(interface); - - } - } // forearch interface - } - else - { - error = metaData->getLatestError(); - iLatestError = error; - XQSERVICE_DEBUG_PRINT("metadata error: %d", error); - } - - delete metaData; - metaData = NULL; - res.Close(); - - - // If only first found needed, quit the loop. - if (findFirst && firstUidPicked) - { - XQSERVICE_DEBUG_PRINT("First service returned UID3=%x", aAppUid.iUid); - break; - } - - } // for implArray ... - - delete apaInfo; - if (!found) - { - error = KErrNotFound; - } - if (found) - { - error = KErrNone; - } - - XQSERVICE_DEBUG_PRINT("Discover error: %d", error); - - return error; - } - - -TInt XQServiceManagerPrivate::Discover2( const TDesC& aService, - TUid& aAppUid, QList& interfaces, - int matchMode, bool findFirst) - { - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover2"); - - CApaAppServiceInfoArray* apaInfo = NULL; - TInt error = KErrNone; - - TRAP(error, apaInfo = AvailableServiceImplementations2L()); - XQSERVICE_DEBUG_PRINT("Discover status=%d", error); - - if (error) - { - return error; // This is fatal as nothing found - } - TArray implArray( apaInfo->Array() ); - XQSERVICE_DEBUG_PRINT("implArray.Count(): %d", implArray.Count()); - - if ( !implArray.Count() ) - { - delete apaInfo; - return KErrNotFound; // No services found - } - - TBool found( EFalse ); - - QString serviceName = QString::fromUtf16(aService.Ptr(),aService.Length()); - XQSERVICE_DEBUG_PRINT("serviceName: %s", qPrintable(serviceName)); - TBool firstUidPicked(EFalse); - - for ( TInt ii = 0; ii < implArray.Count(); ii++ ) - { - TUid uid = implArray[ii].Uid(); - XQSERVICE_DEBUG_PRINT("implArray[%d].UID=%x", ii, uid); - - QByteArray xmlConf ; - - TPtrC8 opaque = implArray[ii].OpaqueData(); - const TPtrC16 tmpXml((TText16*) opaque.Ptr(),(opaque.Length()+1)>>1); - QString strXml = XQConversions:: s60DescToQString( tmpXml ) ; - // XQSERVICE_DEBUG_PRINT("XML conf: %s", qPrintable(strXml)); - XQSERVICE_DEBUG_PRINT("size of xml conf.: %d characters", strXml.size()); - xmlConf.append(strXml.toAscii()); - - XQSERVICE_DEBUG_PRINT("resource data: %s", xmlConf.constData()); - QBuffer buf(&xmlConf); - ServiceMetaData* metaData = new ServiceMetaData(&buf); - if (metaData->extractMetadata()) - { - ServiceMetaDataResults results=metaData->parseResults(); - - // Go through all interfaces and pick the UI for the first matching one. - // THIS NEED TO BE FIXED IF SOMEONE WANTS DEDICATED IMPLEMENTATION - // Fill in the implementationId for all interfaces - foreach (XQAiwInterfaceDescriptor interface,results.interfaces) - { - QString sn; - QString snDeprecated; - if (results.version == ServiceMetaDataResults::VERSION_1) - { - // Old version of the XML format. The parser took care of adaptation - // discovery-name = service-name + interface name - XQSERVICE_DEBUG_PRINT("version 1"); - } - else - { - // discovery-name = interface name - XQSERVICE_DEBUG_PRINT("version 2"); - } - - // Deprecated service name, if any - QString deprecatedServiceName = interface.customProperty("deprecatedsn"); - bool deprNameExists = !deprecatedServiceName.isEmpty(); - if (deprNameExists) - { - XQSERVICE_DEBUG_PRINT("deprecatedServiceName: %s", qPrintable(deprecatedServiceName)); - } - // This is the name used in match - // TODO: Version handling support: Take the latest version if multiple matches - switch (matchMode) - { - case MatchInterfaceName : - sn = interface.interfaceName(); - break; - case MatchServiceAndInterfaceName : - sn =interface.serviceName() + "." + interface.interfaceName(); - snDeprecated = deprecatedServiceName + "." + interface.interfaceName(); - break; - default: - sn = interface.interfaceName(); - break; - } - - XQSERVICE_DEBUG_PRINT("compare name is: %s", qPrintable(sn)); - XQSERVICE_DEBUG_PRINT("requested name: %s", qPrintable(serviceName)); - if ((!serviceName.compare(sn,Qt::CaseInsensitive)) || - (deprNameExists && !serviceName.compare(snDeprecated,Qt::CaseInsensitive))) - { - TUid appUid = implArray[ii].Uid(); - if (!firstUidPicked) - { - aAppUid = appUid; - firstUidPicked = ETrue; - XQSERVICE_DEBUG_PRINT("First service found UID3=%x", appUid.iUid); - } - XQSERVICE_DEBUG_PRINT("Service found UID3=%x", appUid.iUid); - // Add impl. UID to interface - interface.setProperty(XQAiwInterfaceDescriptor::ImplementationId, (int)appUid.iUid); - found = ETrue; - - // Add the matched interface to result set - interfaces.append(interface); - } - - if (found) - { - error = KErrNone; - } - } // forearch interface - } - else - { - error = metaData->getLatestError(); - iLatestError = error; - XQSERVICE_DEBUG_PRINT("metadata error: %d", error); - } - - delete metaData; - metaData = NULL; - - // If only first found needed, quit the loop. - if (findFirst && firstUidPicked) - { - XQSERVICE_DEBUG_PRINT("First service returned UID3=%x", aAppUid.iUid); - break; - } - } // for implArray ... - - delete apaInfo; - if (!found) - { - error = KErrNotFound; - } - - if (found) - { - error = KErrNone; - } - - XQSERVICE_DEBUG_PRINT("Discover error: %d", error); - - return error; -} - -bool XQServiceManagerPrivate::IsRunning(const XQAiwInterfaceDescriptor& implementation) const -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::IsRunning"); - QString fullServiceName = implementation.serviceName() + "." + implementation.interfaceName(); - TPtrC serverName( reinterpret_cast(fullServiceName.utf16()) ); - - TFindServer findServer(serverName); - TFullName name; - bool b = findServer.Next(name) == KErrNone; - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::IsRunning=%d",b); - return b; -} - - -int XQServiceManagerPrivate::doMapErrors(TInt aError) -{ - XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::doMapErrors"); - XQSERVICE_DEBUG_PRINT("aError: %d", aError); - int error(XQService::ENoError); - - switch (aError) - { - case KErrNone: { - error = XQService::ENoError; - break; - } - case KErrPermissionDenied: - case KErrServerTerminated: { - error = XQService::EConnectionClosed; - break; - } - case KErrServerBusy: { - error = XQService::EConnectionError; - break; - } - case KErrArgument: - { - error = XQService::EArgumentError; - break; - } - - case KErrNoMemory: { - error = XQService::EIPCError; - break; - } - case KErrNotFound: { - error = XQService::EServerNotFound; - break; - } - - default: - { - - if (aError >= XQService::EMetaNoService && aError <= XQService::EMetaDuplicatedCustomKey) - { - iLatestError = error; - return error; // Already real error - } - - error = XQService::EUnknownError; - break; - } - } - - // Save error - iLatestError = error; - - XQSERVICE_DEBUG_PRINT("error: %d", error); - return error; -} - - -