|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "databasemanager_s60_p.h" |
|
43 #include "clientservercommon.h" |
|
44 #include <qserviceinterfacedescriptor_p.h> |
|
45 #include <qserviceinterfacedescriptor.h> |
|
46 #include <qservicefilter.h> |
|
47 #include <QProcess> |
|
48 #include <QDebug> |
|
49 #include <s32mem.h> |
|
50 |
|
51 |
|
52 QTM_BEGIN_NAMESPACE |
|
53 |
|
54 /* |
|
55 \class DatabaseManager |
|
56 \ingroup servicesfw |
|
57 \brief The database manager is responsible for receiving queries |
|
58 about services and managing user and system scope databases in order to |
|
59 respond to those queries. |
|
60 |
|
61 The DatabaseManager provides operations for |
|
62 - registering and unregistering services |
|
63 - querying for services and interfaces |
|
64 - setting and getting default interface implementations |
|
65 |
|
66 and provides notifications by emitting signals for added |
|
67 or removed services. |
|
68 |
|
69 Implementation note: |
|
70 When one of the above operations is first invoked a connection with the |
|
71 appropriate database(s) is opened. This connection remains |
|
72 open until the DatabaseManager is destroyed. |
|
73 |
|
74 If the system scope database cannot be opened when performing |
|
75 user scope operations. The operations are carried out as per normal |
|
76 but only acting on the user scope database. Each operation invokation |
|
77 will try to open a connection with the system scope database. |
|
78 |
|
79 Terminology note: |
|
80 When referring to user scope regarding operations, it generally |
|
81 means access to both the user and system databases with the |
|
82 data from both combined into a single dataset. |
|
83 When referring to a user scope database it means the |
|
84 user database only. |
|
85 */ |
|
86 |
|
87 /* |
|
88 \fn DatabaseManager::DatabaseManager() |
|
89 |
|
90 Constructor |
|
91 */ |
|
92 DatabaseManager::DatabaseManager() |
|
93 { |
|
94 int err = iSession.Connect(); |
|
95 |
|
96 int i = 0; |
|
97 while (err != KErrNone) { |
|
98 if (i > 10) |
|
99 qt_symbian_throwIfError(err); |
|
100 |
|
101 User::After(50); |
|
102 err = iSession.Connect(); |
|
103 i++; |
|
104 } |
|
105 |
|
106 iDatabaseManagerSignalMonitor = new DatabaseManagerSignalMonitor(*this, iSession); |
|
107 } |
|
108 |
|
109 /* |
|
110 \fn DatabaseManager::~DatabaseManager() |
|
111 |
|
112 Destructor |
|
113 */ |
|
114 DatabaseManager::~DatabaseManager() |
|
115 { |
|
116 delete iDatabaseManagerSignalMonitor; |
|
117 iSession.Close(); |
|
118 } |
|
119 |
|
120 /* |
|
121 \fn bool DatabaseManager::registerService(ServiceMetaDataResults &service, DbScope scope) |
|
122 |
|
123 Adds the details \a service into the service database corresponding to |
|
124 \a scope. |
|
125 |
|
126 Returns true if the operation succeeded and false otherwise. |
|
127 The last error is set when this function is called. |
|
128 */ |
|
129 bool DatabaseManager::registerService(ServiceMetaDataResults &service, DbScope scope) |
|
130 { |
|
131 Q_UNUSED(scope); |
|
132 return iSession.RegisterService(service); |
|
133 } |
|
134 |
|
135 /* |
|
136 \fn bool DatabaseManager::unregisterService(const QString &serviceName, DbScope scope) |
|
137 |
|
138 Removes the details of \a serviceName from the database corresponding to \a |
|
139 scope. |
|
140 |
|
141 Returns true if the operation succeeded, false otherwise. |
|
142 The last error is set when this function is called. |
|
143 */ |
|
144 bool DatabaseManager::unregisterService(const QString &serviceName, DbScope scope) |
|
145 { |
|
146 Q_UNUSED(scope); |
|
147 return iSession.UnregisterService(serviceName); |
|
148 } |
|
149 |
|
150 /* |
|
151 \fn QList<QServiceInterfaceDescriptor> DatabaseManager::getInterfaces(const QServiceFilter &filter, DbScope scope) |
|
152 |
|
153 Retrieves a list of interface descriptors that fulfill the constraints specified |
|
154 by \a filter at a given \a scope. |
|
155 |
|
156 The last error is set when this function is called. |
|
157 */ |
|
158 QList<QServiceInterfaceDescriptor> DatabaseManager::getInterfaces(const QServiceFilter &filter, DbScope scope) |
|
159 { |
|
160 Q_UNUSED(scope); |
|
161 return iSession.Interfaces(filter); |
|
162 } |
|
163 |
|
164 |
|
165 /* |
|
166 \fn QStringList DatabaseManager::getServiceNames(const QString &interfaceName, DbScope scope) |
|
167 |
|
168 Retrieves a list of the names of services that provide the interface |
|
169 specified by \a interfaceName. |
|
170 |
|
171 The last error is set when this function is called. |
|
172 */ |
|
173 QStringList DatabaseManager::getServiceNames(const QString &interfaceName, DbScope scope) |
|
174 { |
|
175 Q_UNUSED(scope); |
|
176 return iSession.ServiceNames(interfaceName); |
|
177 } |
|
178 |
|
179 /* |
|
180 \fn QServiceInterfaceDescriptor DatabaseManager::interfaceDefault(const QString &interfaceName, DbScope scope) |
|
181 |
|
182 Returns the default interface implementation descriptor for a given |
|
183 \a interfaceName and \a scope. |
|
184 |
|
185 The last error is set when this function is called. |
|
186 */ |
|
187 QServiceInterfaceDescriptor DatabaseManager::interfaceDefault(const QString &interfaceName, DbScope scope) |
|
188 { |
|
189 Q_UNUSED(scope); |
|
190 return iSession.InterfaceDefault(interfaceName); |
|
191 } |
|
192 |
|
193 /* |
|
194 \fn bool DatabaseManager::setInterfaceDefault(const QString &serviceName, const QString &interfaceName, DbScope scope) |
|
195 |
|
196 Sets the default interface implemenation for \a interfaceName to the matching |
|
197 interface implementation provided by \a service. |
|
198 |
|
199 If \a service provides more than one interface implementation, the newest |
|
200 version of the interface is set as the default. |
|
201 |
|
202 Returns true if the operation was succeeded, false otherwise |
|
203 The last error is set when this function is called. |
|
204 */ |
|
205 bool DatabaseManager::setInterfaceDefault(const QString &serviceName, const |
|
206 QString &interfaceName, DbScope scope) { |
|
207 Q_UNUSED(scope); |
|
208 return iSession.SetInterfaceDefault(serviceName, interfaceName); |
|
209 } |
|
210 |
|
211 /* |
|
212 \fn bool DatabaseManager::setInterfaceDefault(const QServiceInterfaceDescriptor &descriptor, DbScope scope) |
|
213 |
|
214 Sets the interface implementation specified by \a descriptor to be the default |
|
215 implementation for the particular interface specified in the descriptor. |
|
216 |
|
217 Returns true if the operation succeeded, false otherwise. |
|
218 The last error is set when this function is called. |
|
219 */ |
|
220 bool DatabaseManager::setInterfaceDefault(const QServiceInterfaceDescriptor &descriptor, DbScope scope) |
|
221 { |
|
222 Q_UNUSED(scope); |
|
223 return iSession.SetInterfaceDefault(descriptor); |
|
224 } |
|
225 |
|
226 /* |
|
227 \fn void DatabaseManager::setChangeNotificationsEnabled(DbScope scope, bool enabled) |
|
228 |
|
229 Sets whether change notifications for added and removed services are |
|
230 \a enabled or not at a given \a scope. |
|
231 */ |
|
232 void DatabaseManager::setChangeNotificationsEnabled(DbScope scope, bool enabled) |
|
233 { |
|
234 Q_UNUSED(scope); |
|
235 iSession.SetChangeNotificationsEnabled(enabled); |
|
236 } |
|
237 |
|
238 DatabaseManagerSignalMonitor::DatabaseManagerSignalMonitor( |
|
239 DatabaseManager& databaseManager, RDatabaseManagerSession& databaseManagerSession) : |
|
240 CActive(EPriorityNormal), |
|
241 iDatabaseManager(databaseManager), iDatabaseManagerSession(databaseManagerSession) |
|
242 { |
|
243 CActiveScheduler::Add(this); |
|
244 issueNotifyServiceSignal(); |
|
245 } |
|
246 |
|
247 DatabaseManagerSignalMonitor::~DatabaseManagerSignalMonitor() |
|
248 { |
|
249 Cancel(); |
|
250 } |
|
251 |
|
252 void DatabaseManagerSignalMonitor::issueNotifyServiceSignal() |
|
253 { |
|
254 iDatabaseManagerSession.NotifyServiceSignal(iStatus); |
|
255 SetActive(); |
|
256 } |
|
257 |
|
258 DBError DatabaseManager::lastError() |
|
259 { |
|
260 return iSession.LastError(); |
|
261 } |
|
262 |
|
263 void DatabaseManagerSignalMonitor::DoCancel() |
|
264 { |
|
265 iDatabaseManagerSession.CancelNotifyServiceSignal(); |
|
266 } |
|
267 |
|
268 void DatabaseManagerSignalMonitor::RunL() |
|
269 { |
|
270 switch (iStatus.Int()) |
|
271 { |
|
272 case ENotifySignalComplete: |
|
273 { |
|
274 QString serviceName = QString::fromUtf16(iDatabaseManagerSession.iServiceName.Ptr(), iDatabaseManagerSession.iServiceName.Length()); |
|
275 |
|
276 if ((DatabaseManager::State)iDatabaseManagerSession.iState() == DatabaseManager::EAdded) |
|
277 { |
|
278 emit iDatabaseManager.serviceAdded(serviceName, DatabaseManager::SystemScope); |
|
279 } |
|
280 else if ((DatabaseManager::State)iDatabaseManagerSession.iState() == DatabaseManager::ERemoved) |
|
281 { |
|
282 emit iDatabaseManager.serviceRemoved(serviceName, DatabaseManager::SystemScope); |
|
283 } |
|
284 issueNotifyServiceSignal(); |
|
285 break; |
|
286 } |
|
287 default: |
|
288 { |
|
289 |
|
290 } |
|
291 break; |
|
292 } |
|
293 } |
|
294 |
|
295 |
|
296 RDatabaseManagerSession::RDatabaseManagerSession() |
|
297 : RSessionBase() |
|
298 { |
|
299 #ifdef __WINS__ |
|
300 iServerThread = NULL; |
|
301 #endif |
|
302 } |
|
303 |
|
304 TVersion RDatabaseManagerSession::Version() const |
|
305 { |
|
306 return TVersion(KServerMajorVersionNumber, KServerMinorVersionNumber, KServerBuildVersionNumber); |
|
307 } |
|
308 |
|
309 TInt RDatabaseManagerSession::Connect() |
|
310 { |
|
311 TInt err = StartServer(); |
|
312 if (err == KErrNone) |
|
313 { |
|
314 err = CreateSession(KDatabaseManagerServerName, Version()); //Default message slots |
|
315 } |
|
316 return err; |
|
317 } |
|
318 |
|
319 TInt RDatabaseManagerSession::StartServer() |
|
320 { |
|
321 TInt ret = KErrNone; |
|
322 TFindServer findServer(KDatabaseManagerServerName); |
|
323 TFullName name; |
|
324 |
|
325 if (findServer.Next(name) != KErrNone) |
|
326 { |
|
327 #ifdef __WINS__ |
|
328 iServerThread = new CDatabaseManagerServerThread(); |
|
329 iServerThread->start(); |
|
330 iServerThread->wait(1); |
|
331 #else |
|
332 TRequestStatus status; |
|
333 RProcess dbServer; |
|
334 ret = dbServer.Create(KDatabaseManagerServerName, KNullDesC); |
|
335 if(ret != KErrNone) |
|
336 { |
|
337 return ret; |
|
338 } |
|
339 dbServer.Rendezvous(status); |
|
340 if(status != KRequestPending) |
|
341 { |
|
342 dbServer.Kill(KErrNone); |
|
343 dbServer.Close(); |
|
344 return KErrGeneral; |
|
345 } |
|
346 else |
|
347 { |
|
348 dbServer.Resume(); |
|
349 } |
|
350 |
|
351 User::WaitForRequest(status); |
|
352 if(status != KErrNone) |
|
353 { |
|
354 dbServer.Close(); |
|
355 return status.Int(); |
|
356 } |
|
357 dbServer.Close(); |
|
358 #endif |
|
359 } |
|
360 |
|
361 return ret; |
|
362 } |
|
363 |
|
364 void RDatabaseManagerSession::Close() |
|
365 { |
|
366 RSessionBase::Close(); |
|
367 } |
|
368 |
|
369 bool RDatabaseManagerSession::RegisterService(ServiceMetaDataResults& aService) |
|
370 { |
|
371 QByteArray serviceByteArray; |
|
372 QDataStream in(&serviceByteArray, QIODevice::WriteOnly); |
|
373 in.setVersion(QDataStream::Qt_4_6); |
|
374 in << aService; |
|
375 TPtrC8 ptr8((TUint8*)(serviceByteArray.constData()), serviceByteArray.size()); |
|
376 TIpcArgs args(&ptr8, &iError); |
|
377 SendReceive(ERegisterServiceRequest, args); |
|
378 |
|
379 return (iError() == DBError::NoError); |
|
380 } |
|
381 |
|
382 bool RDatabaseManagerSession::UnregisterService(const QString& aServiceName) |
|
383 { |
|
384 TPtrC serviceNamePtr(reinterpret_cast<const TUint16*>(aServiceName.utf16())); |
|
385 TIpcArgs args(&serviceNamePtr, &iError); |
|
386 SendReceive(EUnregisterServiceRequest, args); |
|
387 |
|
388 return (iError() == DBError::NoError); |
|
389 } |
|
390 |
|
391 QList<QServiceInterfaceDescriptor> RDatabaseManagerSession::Interfaces(const QServiceFilter& aFilter) |
|
392 { |
|
393 QByteArray filterByteArray; |
|
394 QDataStream in(&filterByteArray, QIODevice::WriteOnly); |
|
395 in.setVersion(QDataStream::Qt_4_6); |
|
396 in << aFilter; |
|
397 TPtrC8 ptr8((TUint8*)(filterByteArray.constData()), filterByteArray.size()); |
|
398 TPckgBuf<TInt> lengthPckg(0); |
|
399 TIpcArgs args(&ptr8, &lengthPckg, &iError); |
|
400 SendReceive(EGetInterfacesSizeRequest, args); |
|
401 |
|
402 HBufC8* descriptorListBuf = HBufC8::New(lengthPckg()); |
|
403 TPtr8 ptrToBuf(descriptorListBuf->Des()); |
|
404 TIpcArgs args2(&ptrToBuf); |
|
405 SendReceive(EGetInterfacesRequest, args2); |
|
406 |
|
407 QByteArray descriptorListByteArray((const char*)ptrToBuf.Ptr(), ptrToBuf.Length()); |
|
408 QDataStream out(descriptorListByteArray); |
|
409 QList<QServiceInterfaceDescriptor> descriptorList; |
|
410 out >> descriptorList; |
|
411 |
|
412 delete descriptorListBuf; |
|
413 |
|
414 return descriptorList; |
|
415 } |
|
416 |
|
417 QStringList RDatabaseManagerSession::ServiceNames(const QString& aInterfaceName) |
|
418 { |
|
419 TPtrC interfaceNamePtr(reinterpret_cast<const TUint16*>(aInterfaceName.utf16())); |
|
420 HBufC* interfaceNamebuf = HBufC::New(interfaceNamePtr.Length()); |
|
421 interfaceNamebuf->Des().Copy(interfaceNamePtr); |
|
422 TPckgBuf<TInt> lengthPckg(0); |
|
423 TIpcArgs args(interfaceNamebuf, &lengthPckg, &iError); |
|
424 SendReceive(EGetServiceNamesSizeRequest, args); |
|
425 |
|
426 HBufC8* serviceNamesBuf = HBufC8::New(lengthPckg()); |
|
427 TPtr8 ptrToBuf(serviceNamesBuf->Des()); |
|
428 TIpcArgs args2(&ptrToBuf); |
|
429 SendReceive(EGetServiceNamesRequest, args2); |
|
430 |
|
431 QByteArray nameListByteArray((const char*)ptrToBuf.Ptr(), ptrToBuf.Length()); |
|
432 QDataStream out(nameListByteArray); |
|
433 QStringList nameList; |
|
434 out >> nameList; |
|
435 |
|
436 delete interfaceNamebuf; |
|
437 delete serviceNamesBuf; |
|
438 |
|
439 return nameList; |
|
440 } |
|
441 |
|
442 QServiceInterfaceDescriptor RDatabaseManagerSession::InterfaceDefault(const QString& aInterfaceName) |
|
443 { |
|
444 TPtrC interfaceNamePtr(reinterpret_cast<const TUint16*>(aInterfaceName.utf16())); |
|
445 HBufC* interfaceNameBuf = HBufC::New(interfaceNamePtr.Length()); |
|
446 interfaceNameBuf->Des().Copy(interfaceNamePtr); |
|
447 TPckgBuf<TInt> lengthPckg(0); |
|
448 TIpcArgs args(interfaceNameBuf, &lengthPckg, &iError); |
|
449 SendReceive(EInterfaceDefaultSizeRequest, args); |
|
450 |
|
451 HBufC8* interfaceDescriptorBuf = HBufC8::New(lengthPckg()); |
|
452 TPtr8 ptrToBuf(interfaceDescriptorBuf->Des()); |
|
453 TIpcArgs args2(&ptrToBuf); |
|
454 SendReceive(EInterfaceDefaultRequest, args2); |
|
455 |
|
456 QByteArray interfaceDescriptorByteArray((const char*)interfaceDescriptorBuf->Ptr(), interfaceDescriptorBuf->Length()); |
|
457 QDataStream out(interfaceDescriptorByteArray); |
|
458 QServiceInterfaceDescriptor interfaceDescriptor; |
|
459 out >> interfaceDescriptor; |
|
460 |
|
461 delete interfaceNameBuf; |
|
462 delete interfaceDescriptorBuf; |
|
463 |
|
464 return interfaceDescriptor; |
|
465 } |
|
466 |
|
467 bool RDatabaseManagerSession::SetInterfaceDefault(const QString &aServiceName, const QString &aInterfaceName) |
|
468 { |
|
469 TPtrC serviceNamePtr(reinterpret_cast<const TUint16*>(aServiceName.utf16())); |
|
470 TPtrC interfaceNamePtr(reinterpret_cast<const TUint16*>(aInterfaceName.utf16())); |
|
471 TIpcArgs args(&serviceNamePtr, &interfaceNamePtr, &iError); |
|
472 SendReceive(ESetInterfaceDefault, args); |
|
473 |
|
474 return (iError() == DBError::NoError); |
|
475 } |
|
476 |
|
477 bool RDatabaseManagerSession::SetInterfaceDefault(const QServiceInterfaceDescriptor &aInterface) |
|
478 { |
|
479 QByteArray interfaceByteArray; |
|
480 QDataStream in(&interfaceByteArray, QIODevice::WriteOnly); |
|
481 in.setVersion(QDataStream::Qt_4_6); |
|
482 in << aInterface; |
|
483 TPtrC8 ptr8((TUint8 *)(interfaceByteArray.constData()), interfaceByteArray.size()); |
|
484 TIpcArgs args(&ptr8, &iError); |
|
485 SendReceive(ESetInterfaceDefault2, args); |
|
486 |
|
487 return (iError() == DBError::NoError); |
|
488 } |
|
489 |
|
490 DBError RDatabaseManagerSession::LastError() |
|
491 { |
|
492 DBError error; |
|
493 error.setError((DBError::ErrorCode)iError()); |
|
494 return error; |
|
495 } |
|
496 |
|
497 void RDatabaseManagerSession::SetChangeNotificationsEnabled(bool aEnabled) |
|
498 { |
|
499 TIpcArgs args((aEnabled ? 1 : 0), &iError); |
|
500 SendReceive(ESetChangeNotificationsEnabledRequest, args); |
|
501 } |
|
502 |
|
503 void RDatabaseManagerSession::NotifyServiceSignal(TRequestStatus& aStatus) |
|
504 { |
|
505 iArgs.Set(0, &iServiceName); |
|
506 iArgs.Set(1, &iState); |
|
507 iArgs.Set(2, &iError); |
|
508 SendReceive(ENotifyServiceSignalRequest, iArgs, aStatus); |
|
509 } |
|
510 |
|
511 void RDatabaseManagerSession::CancelNotifyServiceSignal() const |
|
512 { |
|
513 SendReceive(ECancelNotifyServiceSignalRequest, TIpcArgs(NULL)); |
|
514 } |
|
515 |
|
516 |
|
517 #ifdef __WINS__ |
|
518 QTM_END_NAMESPACE |
|
519 #include "databasemanagerserver.h" |
|
520 QTM_BEGIN_NAMESPACE |
|
521 |
|
522 CDatabaseManagerServerThread::CDatabaseManagerServerThread() |
|
523 { |
|
524 } |
|
525 |
|
526 void CDatabaseManagerServerThread::run() |
|
527 { |
|
528 CDatabaseManagerServer *dbManagerServer = new CDatabaseManagerServer(); |
|
529 __ASSERT_ALWAYS(dbManagerServer != NULL, CDatabaseManagerServer::PanicServer(ESrvCreateServer)); |
|
530 |
|
531 TInt err = dbManagerServer->Start(KDatabaseManagerServerName); |
|
532 if (err != KErrNone) |
|
533 { |
|
534 CDatabaseManagerServer::PanicServer(ESvrStartServer); |
|
535 } |
|
536 RThread::Rendezvous(KErrNone); |
|
537 |
|
538 exec(); |
|
539 |
|
540 delete dbManagerServer; |
|
541 } |
|
542 #endif |
|
543 |
|
544 #include "moc_databasemanager_s60_p.cpp" |
|
545 |
|
546 QTM_END_NAMESPACE |