59 |
59 |
60 int StartServer(const QString& aService, bool embedded, int& applicationUid, quint64& processId, |
60 int StartServer(const QString& aService, bool embedded, int& applicationUid, quint64& processId, |
61 XQRequestUtil *util); |
61 XQRequestUtil *util); |
62 TInt Discover(const QString& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode); |
62 TInt Discover(const QString& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode); |
63 int LatestError() const {return iLatestError;}; |
63 int LatestError() const {return iLatestError;}; |
|
64 bool IsRunning(const XQAiwInterfaceDescriptor& implementation) const; |
64 |
65 |
65 private: |
66 private: |
66 void StartServerL(const TUid& uid, bool embedded, TUint64& processId, XQRequestUtil *util); |
67 void StartServerL(const TUid& uid, bool embedded, TUint64& processId, XQRequestUtil *util); |
67 TInt Discover(const TDesC& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode); |
68 TInt Discover(const TDesC& aService,TUid& aAppUid, QList<XQAiwInterfaceDescriptor>& interfaces, int matchMode); |
68 CApaAppServiceInfoArray* AvailableServiceImplementationsL(); |
69 CApaAppServiceInfoArray* AvailableServiceImplementationsL(); |
158 int XQServiceManager::latestError() const |
159 int XQServiceManager::latestError() const |
159 { |
160 { |
160 return d->LatestError(); |
161 return d->LatestError(); |
161 } |
162 } |
162 |
163 |
|
164 /*! |
|
165 Returns the latest error occured |
|
166 */ |
|
167 bool XQServiceManager::isRunning(const XQAiwInterfaceDescriptor& implementation) const |
|
168 { |
|
169 XQSERVICE_DEBUG_PRINT("XQServiceManager::isRunning"); |
|
170 return d->IsRunning(implementation); |
|
171 } |
|
172 |
|
173 |
163 // aService is here the full name (service + interface) |
174 // aService is here the full name (service + interface) |
164 int XQServiceManagerPrivate::StartServer(const QString& aService, bool embedded, int& applicationUid, quint64& processId, |
175 int XQServiceManagerPrivate::StartServer(const QString& aService, bool embedded, int& applicationUid, quint64& processId, |
165 XQRequestUtil *util) |
176 XQRequestUtil *util) |
166 { |
177 { |
167 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::startServer(2)"); |
178 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::startServer(2)"); |
168 XQSERVICE_DEBUG_PRINT("aService: %s, embedded: %d", qPrintable(aService), embedded); |
179 XQSERVICE_DEBUG_PRINT("aService: %s", qPrintable(aService)); |
169 |
180 |
170 TUid appUid; |
181 TUid appUid; |
171 appUid.iUid=0; |
182 appUid.iUid=0; |
172 |
183 |
173 TInt error = KErrNone; |
184 TInt error = KErrNone; |
200 |
211 |
201 void XQServiceManagerPrivate::StartServerL(const TUid& uid, bool embedded, TUint64& processId, |
212 void XQServiceManagerPrivate::StartServerL(const TUid& uid, bool embedded, TUint64& processId, |
202 XQRequestUtil *util) |
213 XQRequestUtil *util) |
203 { |
214 { |
204 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::StartServerL"); |
215 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::StartServerL"); |
205 Q_UNUSED(util); // Currently not used yet. The uid was set by calling function above |
216 Q_UNUSED(embedded); // Not used any more. XQRequestUtil applied instead |
206 |
217 |
207 RApaLsSession apa; |
218 RApaLsSession apa; |
208 User::LeaveIfError( apa.Connect() ); |
219 User::LeaveIfError( apa.Connect() ); |
209 CleanupClosePushL( apa ); |
220 CleanupClosePushL( apa ); |
210 |
221 |
211 |
222 |
212 bool toBackground = false; |
223 bool toBackground = false; |
213 // Apply the utility's option for embedding |
224 // Apply the utility's option for embedding instead |
214 embedded = util->mInfo.isEmbedded(); |
225 bool embed = util->mInfo.isEmbedded(); |
215 toBackground = util->mInfo.isBackground(); |
226 toBackground = util->mInfo.isBackground(); |
216 |
227 |
217 XQSERVICE_DEBUG_PRINT("\tembedded got from utility=%d", embedded); |
228 XQSERVICE_DEBUG_PRINT("\tembedded got from utility=%d", embed); |
218 XQSERVICE_DEBUG_PRINT("\tbackground got from utility=%d", toBackground); |
229 XQSERVICE_DEBUG_PRINT("\tbackground got from utility=%d", toBackground); |
219 |
230 |
220 // retrieve application information |
231 // retrieve application information |
221 User::LeaveIfError( apa.GetAppInfo( iAppInfo, uid ) ); |
232 User::LeaveIfError( apa.GetAppInfo( iAppInfo, uid ) ); |
222 |
233 |
228 toBackground = caps().iLaunchInBackground; |
239 toBackground = caps().iLaunchInBackground; |
229 XQSERVICE_DEBUG_PRINT("\tbackground from apparch=%d", toBackground); |
240 XQSERVICE_DEBUG_PRINT("\tbackground from apparch=%d", toBackground); |
230 } |
241 } |
231 |
242 |
232 // Consistency check |
243 // Consistency check |
233 if (embedded && toBackground) |
244 if (embed && toBackground) |
234 { |
245 { |
235 User::Leave(KErrArgument); |
246 User::Leave(KErrArgument); |
236 } |
247 } |
237 |
248 |
|
249 /* |
|
250 // Using the "iAppInfo.iCaption" is wrong as the channel name (full servicename) shall be used: |
|
251 // e.g. tester's "com.nokia.servicesd.serviceapp.Dialer" or |
|
252 // "com.nokia.servicesd.serviceapp.Dialer.PROCESS-ID" in case of embedded launch |
|
253 // Anyway, this is not needed as the "XQServiceIpcClient::connectToServer()" takes care of the checking logic |
|
254 // earlier (the "startServer" logic will be applied only when needed) |
238 TFindServer find( iAppInfo.iCaption ); |
255 TFindServer find( iAppInfo.iCaption ); |
239 TFullName fullName; |
256 TFullName fullName; |
240 TInt err = find.Next( fullName ); |
257 TInt err = find.Next( fullName ); |
241 XQSERVICE_DEBUG_PRINT("err: %d", err); |
258 XQSERVICE_DEBUG_PRINT("err: %d", err); |
|
259 */ |
|
260 TInt err = KErrNotFound; // Assume not found |
242 if ( err != KErrNone ) |
261 if ( err != KErrNone ) |
243 { |
262 { |
244 CApaCommandLine* cmdLine = CApaCommandLine::NewLC(); |
263 CApaCommandLine* cmdLine = CApaCommandLine::NewLC(); |
245 cmdLine->SetExecutableNameL( iAppInfo.iFullName ); |
264 cmdLine->SetExecutableNameL( iAppInfo.iFullName ); |
246 TApaCommand aLaunchCommand = toBackground ? EApaCommandBackground : EApaCommandRun; |
265 TApaCommand aLaunchCommand = toBackground ? EApaCommandBackground : EApaCommandRun; |
248 |
267 |
249 // just use the Secure ID as server differentiator |
268 // just use the Secure ID as server differentiator |
250 //cmdLine->SetServerRequiredL( uid.iUid ); |
269 //cmdLine->SetServerRequiredL( uid.iUid ); |
251 RProcess client; |
270 RProcess client; |
252 cmdLine->SetServerRequiredL(client.Id().Id()); |
271 cmdLine->SetServerRequiredL(client.Id().Id()); |
253 if (embedded) { |
272 if (embed) { |
254 CCoeEnv* env= CCoeEnv::Static(); |
273 CCoeEnv* env= CCoeEnv::Static(); |
255 if (env) // Could be NULL |
274 if (env) // Could be NULL |
256 { |
275 { |
257 RWindowGroup& wg = env->RootWin(); |
276 RWindowGroup& wg = env->RootWin(); |
258 wg.AllowProcessToCreateChildWindowGroups(iAppInfo.iUid); |
277 wg.AllowProcessToCreateChildWindowGroups(iAppInfo.iUid); |
265 } |
284 } |
266 } |
285 } |
267 else |
286 else |
268 { |
287 { |
269 // Can not be embedded (non GUI client) |
288 // Can not be embedded (non GUI client) |
270 embedded = false; |
289 embed = false; |
271 util->mInfo.setEmbedded(false); |
|
272 } |
290 } |
273 } |
291 } |
274 |
292 |
275 TRequestStatus requestStatusForRendezvous; |
293 TRequestStatus requestStatusForRendezvous; |
276 |
294 |
277 // start application with command line parameters |
295 // start application with command line parameters |
278 //User::LeaveIfError( apa.StartApp( *cmdLine, threadId, &requestStatusForRendezvous) ); |
296 //User::LeaveIfError( apa.StartApp( *cmdLine, threadId, &requestStatusForRendezvous) ); |
279 QString startupArgs = QString::fromLatin1(XQServiceUtils::StartupArgService); |
297 QString startupArgs = QString::fromLatin1(XQServiceUtils::StartupArgService); |
280 if (embedded) |
298 if (embed) |
281 { |
299 { |
282 startupArgs += (" " + QString::fromLatin1(XQServiceUtils::StartupArgEmbedded)); |
300 startupArgs += (" " + QString::fromLatin1(XQServiceUtils::StartupArgEmbedded)); |
283 } |
301 } |
|
302 |
|
303 // |
|
304 // Add interface name and operation (message) name to the command line as startup args. |
|
305 // Usable in practise only for the embedded launch |
|
306 // Can be used by service application to prepare the UI to the coming call. |
|
307 // |
|
308 QStringList l = util->mOperation.split("("); |
|
309 QString oper = l.value(0); // // Pick only the function name and ignore parameters |
|
310 |
|
311 startupArgs += (" " + QString::fromLatin1(XQServiceUtils::StartupArgInterfaceName) + util->mDescriptor.interfaceName() ); |
|
312 startupArgs += (" " + QString::fromLatin1(XQServiceUtils::StartupArgOperationName) + oper); |
|
313 |
284 XQSERVICE_DEBUG_PRINT("\tStartupArgs:%s", qPrintable(startupArgs)); |
314 XQSERVICE_DEBUG_PRINT("\tStartupArgs:%s", qPrintable(startupArgs)); |
285 TPtrC cmdLineArgs( reinterpret_cast<const TUint16*>(startupArgs.utf16()) ); |
315 TPtrC cmdLineArgs( reinterpret_cast<const TUint16*>(startupArgs.utf16()) ); |
286 |
316 |
287 RProcess newApp; |
317 RProcess newApp; |
288 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Creating process"); |
318 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Creating process"); |
358 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover (2)"); |
388 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::Discover (2)"); |
359 |
389 |
360 CApaAppServiceInfoArray* apaInfo = NULL; |
390 CApaAppServiceInfoArray* apaInfo = NULL; |
361 TInt error = KErrNone; |
391 TInt error = KErrNone; |
362 TRAP(error, apaInfo = AvailableServiceImplementationsL()); |
392 TRAP(error, apaInfo = AvailableServiceImplementationsL()); |
363 XQSERVICE_DEBUG_PRINT("error: %d", error); |
393 XQSERVICE_DEBUG_PRINT("Discover status=%d", error); |
364 if (error) |
394 if (error) |
365 { |
395 { |
366 return error; // This is fatal as nothing found |
396 return error; // This is fatal as nothing found |
367 } |
397 } |
368 TArray<TApaAppServiceInfo> implArray( apaInfo->Array() ); |
398 TArray<TApaAppServiceInfo> implArray( apaInfo->Array() ); |
452 // Fill in the implementationId for all interfaces |
482 // Fill in the implementationId for all interfaces |
453 TBool firstUidPicked(EFalse); |
483 TBool firstUidPicked(EFalse); |
454 foreach (XQAiwInterfaceDescriptor interface,results.interfaces) |
484 foreach (XQAiwInterfaceDescriptor interface,results.interfaces) |
455 { |
485 { |
456 QString sn; |
486 QString sn; |
|
487 QString snDeprecated; |
457 if (results.version == ServiceMetaDataResults::VERSION_1) |
488 if (results.version == ServiceMetaDataResults::VERSION_1) |
458 { |
489 { |
459 // Old version of the XML format. The parser took care of adaptation |
490 // Old version of the XML format. The parser took care of adaptation |
460 // discovery-name = service-name + interface name |
491 // discovery-name = service-name + interface name |
461 XQSERVICE_DEBUG_PRINT("version 1"); |
492 XQSERVICE_DEBUG_PRINT("version 1"); |
463 else |
494 else |
464 { |
495 { |
465 // discovery-name = interface name |
496 // discovery-name = interface name |
466 XQSERVICE_DEBUG_PRINT("version 2"); |
497 XQSERVICE_DEBUG_PRINT("version 2"); |
467 } |
498 } |
|
499 |
|
500 // Deprecated service name, if any |
|
501 QString deprecatedServiceName = interface.customProperty("deprecatedsn"); |
|
502 bool deprNameExists = !deprecatedServiceName.isEmpty(); |
|
503 if (deprNameExists) |
|
504 { |
|
505 XQSERVICE_DEBUG_PRINT("deprecatedServiceName: %s", qPrintable(deprecatedServiceName)); |
|
506 } |
|
507 |
468 // This is the name used in match |
508 // This is the name used in match |
469 // TODO: Version handling support: Take the latest version if multiple matches |
509 // TODO: Version handling support: Take the latest version if multiple matches |
470 switch (matchMode) |
510 switch (matchMode) |
471 { |
511 { |
472 case MatchInterfaceName : |
512 case MatchInterfaceName : |
473 sn = interface.interfaceName(); |
513 sn = interface.interfaceName(); |
474 break; |
514 break; |
475 case MatchServiceAndInterfaceName : |
515 case MatchServiceAndInterfaceName : |
476 sn =interface.serviceName() + "." + interface.interfaceName(); |
516 sn =interface.serviceName() + "." + interface.interfaceName(); |
|
517 snDeprecated = deprecatedServiceName + "." + interface.interfaceName(); |
477 break; |
518 break; |
478 default: |
519 default: |
479 sn = interface.interfaceName(); |
520 sn = interface.interfaceName(); |
480 break; |
521 break; |
481 } |
522 } |
482 |
523 |
483 XQSERVICE_DEBUG_PRINT("compare name is: %s", qPrintable(sn)); |
524 XQSERVICE_DEBUG_PRINT("compare name is: %s", qPrintable(sn)); |
484 XQSERVICE_DEBUG_PRINT("requested name: %s", qPrintable(serviceName)); |
525 XQSERVICE_DEBUG_PRINT("requested name: %s", qPrintable(serviceName)); |
485 if (!serviceName.compare(sn,Qt::CaseInsensitive)) |
526 if ((!serviceName.compare(sn,Qt::CaseInsensitive)) || |
|
527 (deprNameExists && !serviceName.compare(snDeprecated,Qt::CaseInsensitive))) |
486 { |
528 { |
487 if (!firstUidPicked) |
529 if (!firstUidPicked) |
488 { |
530 { |
489 aAppUid = implArray[ii].Uid(); |
531 aAppUid = implArray[ii].Uid(); |
490 firstUidPicked = ETrue; |
532 firstUidPicked = ETrue; |
521 XQSERVICE_DEBUG_PRINT("Discover error: %d", error); |
563 XQSERVICE_DEBUG_PRINT("Discover error: %d", error); |
522 |
564 |
523 return error; |
565 return error; |
524 } |
566 } |
525 |
567 |
|
568 bool XQServiceManagerPrivate::IsRunning(const XQAiwInterfaceDescriptor& implementation) const |
|
569 { |
|
570 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::IsRunning"); |
|
571 QString fullServiceName = implementation.serviceName() + "." + implementation.interfaceName(); |
|
572 TPtrC serverName( reinterpret_cast<const TUint16*>(fullServiceName.utf16()) ); |
|
573 |
|
574 TFindServer findServer(serverName); |
|
575 TFullName name; |
|
576 bool b = findServer.Next(name) == KErrNone; |
|
577 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::IsRunning=%d",b); |
|
578 return b; |
|
579 } |
|
580 |
|
581 |
526 int XQServiceManagerPrivate::doMapErrors(TInt aError) |
582 int XQServiceManagerPrivate::doMapErrors(TInt aError) |
527 { |
583 { |
528 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::doMapErrors"); |
584 XQSERVICE_DEBUG_PRINT("XQServiceManagerPrivate::doMapErrors"); |
529 XQSERVICE_DEBUG_PRINT("aError: %d", aError); |
585 XQSERVICE_DEBUG_PRINT("aError: %d", aError); |
530 int error(XQService::ENoError); |
586 int error(XQService::ENoError); |