17 * |
17 * |
18 * Description: |
18 * Description: |
19 * |
19 * |
20 */ |
20 */ |
21 |
21 |
22 #include "xqservicelog.h" |
|
23 #include <xqserviceglobal.h> |
|
24 |
|
25 #include "xqrequestutil.h" |
|
26 |
|
27 #include "xqservicemanager.h" |
|
28 #include "xqserviceipcconst.h" |
|
29 #include <QCoreApplication> |
|
30 #include <e32std.h> |
22 #include <e32std.h> |
31 #include <w32std.h> |
23 #include <w32std.h> |
32 |
24 #include <apaidpartner.h> |
33 #include <apparc.h> |
25 #include <apparc.h> |
34 #include <apgcli.h> |
26 #include <apgcli.h> |
35 #include <apacln.h> |
27 #include <apacln.h> |
36 #include <apgtask.h> |
28 #include <apgtask.h> |
37 #include <barsread2.h> |
29 #include <barsread2.h> |
38 #include <apacmdln.h> |
30 #include <apacmdln.h> |
39 #include <coemain.h> |
31 #include <coemain.h> |
40 |
32 |
41 #include <QBuffer> |
33 #include <QBuffer> |
|
34 #include <QString> |
|
35 #include <QCoreApplication> |
|
36 |
|
37 #include "xqservicelog.h" |
|
38 #include <xqserviceglobal.h> |
|
39 #include "xqrequestutil.h" |
|
40 #include "xqservicemanager.h" |
|
41 #include "xqserviceipcconst.h" |
|
42 |
42 #include "xqservicemetadata/xqservicemetadata_p.h" |
43 #include "xqservicemetadata/xqservicemetadata_p.h" |
43 #include <xqservicemetadata/xqaiwinterfacedescriptor.h> |
44 #include <xqservicemetadata/xqaiwinterfacedescriptor.h> |
44 |
45 #include "xqconversions.h" |
45 #include <QString> |
46 |
46 |
47 |
47 |
48 |
48 class XQServiceManagerPrivate |
49 class XQServiceManagerPrivate |
49 { |
50 { |
50 public: |
51 public: |
51 XQServiceManagerPrivate() {iLatestError = 0;}; |
52 XQServiceManagerPrivate(); |
52 ~XQServiceManagerPrivate() {}; |
53 ~XQServiceManagerPrivate(); |
53 |
54 |
54 enum matchMode |
55 enum matchMode |
55 { |
56 { |
56 MatchInterfaceName, |
57 MatchInterfaceName, |
57 MatchServiceAndInterfaceName |
58 MatchServiceAndInterfaceName |
58 }; |
59 }; |
59 |
60 |
60 int StartServer(const QString& aService, bool embedded, int& applicationUid, quint64& processId, |
61 int StartServer(const QString& aService, bool embedded, int& applicationUid, quint64& processId, |
61 XQRequestUtil *util); |
62 XQRequestUtil *util); |
62 TInt Discover(const QString& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode); |
63 TInt Discover(const QString& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode, |
|
64 bool findFirst=false); |
63 int LatestError() const {return iLatestError;}; |
65 int LatestError() const {return iLatestError;}; |
64 bool IsRunning(const XQAiwInterfaceDescriptor& implementation) const; |
66 bool IsRunning(const XQAiwInterfaceDescriptor& implementation) const; |
65 |
67 |
66 private: |
68 private: |
67 void StartServerL(const TUid& uid, bool embedded, TUint64& processId, XQRequestUtil *util); |
69 void StartServerL(const TUid& uid, bool embedded, TUint64& processId, XQRequestUtil *util); |
68 TInt Discover(const TDesC& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode); |
70 TInt Discover(const TDesC& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode, |
69 CApaAppServiceInfoArray* AvailableServiceImplementationsL(); |
71 bool findFirst=false); |
|
72 TInt Discover1(const TDesC& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode, |
|
73 bool findFirst=false); |
|
74 TInt Discover2(const TDesC& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode, |
|
75 bool findFirst=false); |
|
76 CApaAppServiceInfoArray* AvailableServiceImplementations1L(); |
|
77 CApaAppServiceInfoArray* AvailableServiceImplementations2L(); |
70 TUint64 getAppPid(const TUid& aAppUid); |
78 TUint64 getAppPid(const TUid& aAppUid); |
71 int doMapErrors(TInt aError); |
79 int doMapErrors(TInt aError); |
72 |
80 |
73 TVersion iVersion; |
81 TVersion iVersion; |
74 TApaAppInfo iAppInfo; |
82 TApaAppInfo iAppInfo; |
75 int iLatestError; |
83 int iLatestError; |
|
84 RApaLsSession iApaSession; |
76 }; |
85 }; |
77 |
86 |
78 XQServiceManager::XQServiceManager() |
87 XQServiceManager::XQServiceManager() |
79 { |
88 { |
80 XQSERVICE_DEBUG_PRINT("XQServiceManager::XQServiceManager"); |
89 XQSERVICE_DEBUG_PRINT("XQServiceManager::XQServiceManager"); |
152 return interfaces; |
161 return interfaces; |
153 } |
162 } |
154 |
163 |
155 |
164 |
156 /*! |
165 /*! |
|
166 Finds implementations for the given interface |
|
167 \param interfaceName Interfacename to match |
|
168 \return List of implementations |
|
169 */ |
|
170 QList<XQAiwInterfaceDescriptor> XQServiceManager::findFirstInterface ( const QString &interfaceName ) const |
|
171 { |
|
172 XQSERVICE_DEBUG_PRINT("XQServiceManager::findFirstInterface 1"); |
|
173 QList<XQAiwInterfaceDescriptor> interfaces; |
|
174 TUid appUid; |
|
175 interfaces.clear(); |
|
176 TInt error=d->Discover(interfaceName, appUid, interfaces, XQServiceManagerPrivate::MatchInterfaceName, true); |
|
177 return interfaces; |
|
178 } |
|
179 |
|
180 /*! |
|
181 Finds implementations for the given interface implemented by given service |
|
182 \param serviceName Service name |
|
183 \param interfaceName Interfacename to match |
|
184 \return List of implementations |
|
185 */ |
|
186 QList<XQAiwInterfaceDescriptor> XQServiceManager::findFirstInterface ( const QString &serviceName, const QString &interfaceName ) const |
|
187 { |
|
188 XQSERVICE_DEBUG_PRINT("XQServiceManager::findFirstInterface 2"); |
|
189 QList<XQAiwInterfaceDescriptor> interfaces; |
|
190 TUid appUid; |
|
191 interfaces.clear(); |
|
192 // Catenate to get full name |
|
193 TInt error=d->Discover(serviceName + "." + interfaceName, appUid, interfaces, |
|
194 XQServiceManagerPrivate::MatchServiceAndInterfaceName, true); |
|
195 return interfaces; |
|
196 } |
|
197 |
|
198 |
|
199 |
|
200 /*! |
157 Returns the latest error occured |
201 Returns the latest error occured |
158 */ |
202 */ |
159 int XQServiceManager::latestError() const |
203 int XQServiceManager::latestError() const |
160 { |
204 { |
161 return d->LatestError(); |
205 return d->LatestError(); |
213 XQRequestUtil *util) |
272 XQRequestUtil *util) |
214 { |
273 { |
215 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::StartServerL"); |
274 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::StartServerL"); |
216 Q_UNUSED(embedded); // Not used any more. XQRequestUtil applied instead |
275 Q_UNUSED(embedded); // Not used any more. XQRequestUtil applied instead |
217 |
276 |
218 RApaLsSession apa; |
|
219 User::LeaveIfError( apa.Connect() ); |
|
220 CleanupClosePushL( apa ); |
|
221 |
|
222 |
|
223 bool toBackground = false; |
277 bool toBackground = false; |
224 // Apply the utility's option for embedding instead |
278 // Apply the utility's option for embedding instead |
225 bool embed = util->mInfo.isEmbedded(); |
279 bool embed = util->mInfo.isEmbedded(); |
226 toBackground = util->mInfo.isBackground(); |
280 toBackground = util->mInfo.isBackground(); |
227 |
281 |
228 XQSERVICE_DEBUG_PRINT("\tembedded got from utility=%d", embed); |
282 XQSERVICE_DEBUG_PRINT("\tembedded got from utility=%d", embed); |
229 XQSERVICE_DEBUG_PRINT("\tbackground got from utility=%d", toBackground); |
283 XQSERVICE_DEBUG_PRINT("\tbackground got from utility=%d", toBackground); |
230 |
284 |
231 // retrieve application information |
285 // retrieve application information |
232 User::LeaveIfError( apa.GetAppInfo( iAppInfo, uid ) ); |
286 User::LeaveIfError( iApaSession.GetAppInfo( iAppInfo, uid ) ); |
233 |
287 |
234 TApaAppCapabilityBuf caps; |
288 TApaAppCapabilityBuf caps; |
235 User::LeaveIfError(apa.GetAppCapability(caps, uid)); |
289 User::LeaveIfError(iApaSession.GetAppCapability(caps, uid)); |
236 if (!toBackground) |
290 if (!toBackground) |
237 { |
291 { |
238 // If service wants to be launched to background.. respect it |
292 // If service wants to be launched to background.. respect it |
239 toBackground = caps().iLaunchInBackground; |
293 toBackground = caps().iLaunchInBackground; |
240 XQSERVICE_DEBUG_PRINT("\tbackground from apparch=%d", toBackground); |
294 XQSERVICE_DEBUG_PRINT("\tbackground from apparch=%d", toBackground); |
355 pid=task.ThreadId().Id(); |
408 pid=task.ThreadId().Id(); |
356 } |
409 } |
357 } |
410 } |
358 return pid; |
411 return pid; |
359 } |
412 } |
360 CApaAppServiceInfoArray* XQServiceManagerPrivate::AvailableServiceImplementationsL() |
413 |
361 { |
414 CApaAppServiceInfoArray* XQServiceManagerPrivate::AvailableServiceImplementations1L() |
362 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::AvailableServiceImplementationsL"); |
415 { |
363 RApaLsSession ls; |
416 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::AvailableServiceImplementations1L"); |
364 User::LeaveIfError( ls.Connect() ); |
|
365 CleanupClosePushL( ls ); |
|
366 // retrieve list of available services implementations from apparc |
417 // retrieve list of available services implementations from apparc |
367 CApaAppServiceInfoArray* apaInfo = |
418 CApaAppServiceInfoArray* apaInfo = |
368 ls.GetServiceImplementationsLC(TUid::Uid(KXQServiceUid)); |
419 iApaSession.GetServiceImplementationsLC(TUid::Uid(KXQServiceUid)); |
369 CleanupStack::Pop( apaInfo ); |
420 CleanupStack::Pop( apaInfo ); |
370 CleanupStack::PopAndDestroy( &ls ); |
|
371 return apaInfo; |
421 return apaInfo; |
372 } |
422 } |
373 |
423 |
|
424 CApaAppServiceInfoArray* XQServiceManagerPrivate::AvailableServiceImplementations2L() |
|
425 { |
|
426 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::AvailableServiceImplementations2L"); |
|
427 // retrieve list of available services implementations from apparc |
|
428 CApaAppServiceInfoArray* apaInfo = |
|
429 iApaSession.GetServiceImplementationsLC(TUid::Uid(KXQServiceUid2)); |
|
430 CleanupStack::Pop( apaInfo ); |
|
431 return apaInfo; |
|
432 } |
|
433 |
374 TInt XQServiceManagerPrivate::Discover(const QString& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, |
434 TInt XQServiceManagerPrivate::Discover(const QString& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, |
375 int matchMode) |
435 int matchMode, bool findFirst) |
376 { |
436 { |
377 TPtrC serverName( reinterpret_cast<const TUint16*>(aService.utf16()) ); |
437 TPtrC serverName( reinterpret_cast<const TUint16*>(aService.utf16()) ); |
378 TInt error=Discover(serverName, aAppUid, interfaces, matchMode); |
438 TInt error=Discover(serverName, aAppUid, interfaces, matchMode, findFirst); |
379 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover (1)"); |
439 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover (1)"); |
380 return error; |
440 return error; |
381 } |
441 } |
382 |
442 |
383 |
|
384 TInt XQServiceManagerPrivate::Discover( const TDesC& aService, |
443 TInt XQServiceManagerPrivate::Discover( const TDesC& aService, |
385 TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, |
444 TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, |
386 int matchMode) |
445 int matchMode, bool findFirst) |
387 { |
446 { |
388 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover (2)"); |
447 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover (2)"); |
|
448 TInt discoverResult1 = KErrNotFound; |
|
449 TInt discoverResult2 = KErrNotFound; |
|
450 |
|
451 // Discover first possible reg files with old format |
|
452 discoverResult1 = Discover1(aService, aAppUid, interfaces, matchMode, findFirst); |
|
453 // Discover then reg files with new format (add results) |
|
454 discoverResult2 = Discover2(aService, aAppUid, interfaces, matchMode, findFirst); |
|
455 |
|
456 if (discoverResult1 == KErrNone || discoverResult2 == KErrNone) |
|
457 { |
|
458 // Results merged |
|
459 return KErrNone; |
|
460 } |
|
461 else |
|
462 { |
|
463 return KErrNotFound; |
|
464 } |
|
465 } |
|
466 |
|
467 TInt XQServiceManagerPrivate::Discover1( const TDesC& aService, |
|
468 TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, |
|
469 int matchMode, bool findFirst) |
|
470 { |
|
471 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover1"); |
389 |
472 |
390 CApaAppServiceInfoArray* apaInfo = NULL; |
473 CApaAppServiceInfoArray* apaInfo = NULL; |
391 TInt error = KErrNone; |
474 TInt error = KErrNone; |
392 TRAP(error, apaInfo = AvailableServiceImplementationsL()); |
475 TRAP(error, apaInfo = AvailableServiceImplementations1L()); |
393 XQSERVICE_DEBUG_PRINT("Discover status=%d", error); |
476 XQSERVICE_DEBUG_PRINT("Discover status=%d", error); |
394 if (error) |
477 if (error) |
395 { |
478 { |
396 return error; // This is fatal as nothing found |
479 return error; // This is fatal as nothing found |
397 } |
480 } |
545 } // forearch interface |
629 } // forearch interface |
546 } |
630 } |
547 else |
631 else |
548 { |
632 { |
549 error = metaData->getLatestError(); |
633 error = metaData->getLatestError(); |
|
634 iLatestError = error; |
550 XQSERVICE_DEBUG_PRINT("metadata error: %d", error); |
635 XQSERVICE_DEBUG_PRINT("metadata error: %d", error); |
551 } |
636 } |
552 |
637 |
553 delete metaData; |
638 delete metaData; |
554 metaData = NULL; |
639 metaData = NULL; |
555 res.Close(); |
640 res.Close(); |
|
641 |
|
642 |
|
643 // If only first found needed, quit the loop. |
|
644 if (findFirst && firstUidPicked) |
|
645 { |
|
646 XQSERVICE_DEBUG_PRINT("First service returned UID3=%x", aAppUid.iUid); |
|
647 break; |
|
648 } |
556 |
649 |
557 } // for implArray ... |
650 } // for implArray ... |
558 |
651 |
559 delete apaInfo; |
652 delete apaInfo; |
560 if (!found) |
653 if (!found) |
561 { |
654 { |
562 error = KErrNotFound; |
655 error = KErrNotFound; |
|
656 } |
|
657 if (found) |
|
658 { |
|
659 error = KErrNone; |
|
660 } |
|
661 |
|
662 XQSERVICE_DEBUG_PRINT("Discover error: %d", error); |
|
663 |
|
664 return error; |
|
665 } |
|
666 |
|
667 |
|
668 TInt XQServiceManagerPrivate::Discover2( const TDesC& aService, |
|
669 TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, |
|
670 int matchMode, bool findFirst) |
|
671 { |
|
672 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover2"); |
|
673 |
|
674 CApaAppServiceInfoArray* apaInfo = NULL; |
|
675 TInt error = KErrNone; |
|
676 |
|
677 TRAP(error, apaInfo = AvailableServiceImplementations2L()); |
|
678 XQSERVICE_DEBUG_PRINT("Discover status=%d", error); |
|
679 |
|
680 if (error) |
|
681 { |
|
682 return error; // This is fatal as nothing found |
|
683 } |
|
684 TArray<TApaAppServiceInfo> implArray( apaInfo->Array() ); |
|
685 XQSERVICE_DEBUG_PRINT("implArray.Count(): %d", implArray.Count()); |
|
686 |
|
687 if ( !implArray.Count() ) |
|
688 { |
|
689 delete apaInfo; |
|
690 return KErrNotFound; // No services found |
|
691 } |
|
692 |
|
693 TBool found( EFalse ); |
|
694 |
|
695 QString serviceName = QString::fromUtf16(aService.Ptr(),aService.Length()); |
|
696 XQSERVICE_DEBUG_PRINT("serviceName: %s", qPrintable(serviceName)); |
|
697 TBool firstUidPicked(EFalse); |
|
698 |
|
699 for ( TInt ii = 0; ii < implArray.Count(); ii++ ) |
|
700 { |
|
701 TUid uid = implArray[ii].Uid(); |
|
702 XQSERVICE_DEBUG_PRINT("implArray[%d].UID=%x", ii, uid); |
|
703 |
|
704 QByteArray xmlConf ; |
|
705 |
|
706 TPtrC8 opaque = implArray[ii].OpaqueData(); |
|
707 const TPtrC16 tmpXml((TText16*) opaque.Ptr(),(opaque.Length()+1)>>1); |
|
708 QString strXml = XQConversions:: s60DescToQString( tmpXml ) ; |
|
709 // XQSERVICE_DEBUG_PRINT("XML conf: %s", qPrintable(strXml)); |
|
710 XQSERVICE_DEBUG_PRINT("size of xml conf.: %d characters", strXml.size()); |
|
711 xmlConf.append(strXml.toAscii()); |
|
712 |
|
713 XQSERVICE_DEBUG_PRINT("resource data: %s", xmlConf.constData()); |
|
714 QBuffer buf(&xmlConf); |
|
715 ServiceMetaData* metaData = new ServiceMetaData(&buf); |
|
716 if (metaData->extractMetadata()) |
|
717 { |
|
718 ServiceMetaDataResults results=metaData->parseResults(); |
|
719 |
|
720 // Go through all interfaces and pick the UI for the first matching one. |
|
721 // THIS NEED TO BE FIXED IF SOMEONE WANTS DEDICATED IMPLEMENTATION |
|
722 // Fill in the implementationId for all interfaces |
|
723 foreach (XQAiwInterfaceDescriptor interface,results.interfaces) |
|
724 { |
|
725 QString sn; |
|
726 QString snDeprecated; |
|
727 if (results.version == ServiceMetaDataResults::VERSION_1) |
|
728 { |
|
729 // Old version of the XML format. The parser took care of adaptation |
|
730 // discovery-name = service-name + interface name |
|
731 XQSERVICE_DEBUG_PRINT("version 1"); |
|
732 } |
|
733 else |
|
734 { |
|
735 // discovery-name = interface name |
|
736 XQSERVICE_DEBUG_PRINT("version 2"); |
|
737 } |
|
738 |
|
739 // Deprecated service name, if any |
|
740 QString deprecatedServiceName = interface.customProperty("deprecatedsn"); |
|
741 bool deprNameExists = !deprecatedServiceName.isEmpty(); |
|
742 if (deprNameExists) |
|
743 { |
|
744 XQSERVICE_DEBUG_PRINT("deprecatedServiceName: %s", qPrintable(deprecatedServiceName)); |
|
745 } |
|
746 // This is the name used in match |
|
747 // TODO: Version handling support: Take the latest version if multiple matches |
|
748 switch (matchMode) |
|
749 { |
|
750 case MatchInterfaceName : |
|
751 sn = interface.interfaceName(); |
|
752 break; |
|
753 case MatchServiceAndInterfaceName : |
|
754 sn =interface.serviceName() + "." + interface.interfaceName(); |
|
755 snDeprecated = deprecatedServiceName + "." + interface.interfaceName(); |
|
756 break; |
|
757 default: |
|
758 sn = interface.interfaceName(); |
|
759 break; |
|
760 } |
|
761 |
|
762 XQSERVICE_DEBUG_PRINT("compare name is: %s", qPrintable(sn)); |
|
763 XQSERVICE_DEBUG_PRINT("requested name: %s", qPrintable(serviceName)); |
|
764 if ((!serviceName.compare(sn,Qt::CaseInsensitive)) || |
|
765 (deprNameExists && !serviceName.compare(snDeprecated,Qt::CaseInsensitive))) |
|
766 { |
|
767 TUid appUid = implArray[ii].Uid(); |
|
768 if (!firstUidPicked) |
|
769 { |
|
770 aAppUid = appUid; |
|
771 firstUidPicked = ETrue; |
|
772 XQSERVICE_DEBUG_PRINT("First service found UID3=%x", appUid.iUid); |
|
773 } |
|
774 XQSERVICE_DEBUG_PRINT("Service found UID3=%x", appUid.iUid); |
|
775 // Add impl. UID to interface |
|
776 interface.setProperty(XQAiwInterfaceDescriptor::ImplementationId, (int)aAppUid.iUid); |
|
777 found = ETrue; |
|
778 |
|
779 // Add the matched interface to result set |
|
780 interfaces.append(interface); |
|
781 } |
|
782 |
|
783 if (found) |
|
784 { |
|
785 error = KErrNone; |
|
786 } |
|
787 } // forearch interface |
|
788 } |
|
789 else |
|
790 { |
|
791 error = metaData->getLatestError(); |
|
792 iLatestError = error; |
|
793 XQSERVICE_DEBUG_PRINT("metadata error: %d", error); |
|
794 } |
|
795 |
|
796 delete metaData; |
|
797 metaData = NULL; |
|
798 |
|
799 // If only first found needed, quit the loop. |
|
800 if (findFirst && firstUidPicked) |
|
801 { |
|
802 XQSERVICE_DEBUG_PRINT("First service returned UID3=%x", aAppUid.iUid); |
|
803 break; |
|
804 } |
|
805 } // for implArray ... |
|
806 |
|
807 delete apaInfo; |
|
808 if (!found) |
|
809 { |
|
810 error = KErrNotFound; |
|
811 } |
|
812 |
|
813 if (found) |
|
814 { |
|
815 error = KErrNone; |
563 } |
816 } |
564 |
817 |
565 XQSERVICE_DEBUG_PRINT("Discover error: %d", error); |
818 XQSERVICE_DEBUG_PRINT("Discover error: %d", error); |
566 |
819 |
567 return error; |
820 return error; |