|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalComponent |
|
19 @released |
|
20 */ |
|
21 |
|
22 #include <s32mem.h> |
|
23 #include <cntitem.h> |
|
24 #include <cntdb.h> |
|
25 #include <cntfilt.h> |
|
26 |
|
27 #include "rcntmodel.h" |
|
28 #include "persistencelayer.h" // For MLplCollection. |
|
29 #include "CCntNotificationMonitor.h" |
|
30 #include "ccontactprivate.h" // For MProgressEventHander. |
|
31 #include "CCntPackager.h" |
|
32 #include <cntviewstore.h> |
|
33 |
|
34 |
|
35 /** Contacts server version number. */ |
|
36 const TInt KCntServerMajorVersionNumber=1; |
|
37 const TInt KCntServerMinorVersionNumber=1; |
|
38 const TInt KCntServerBuildVersionNumber=1; |
|
39 |
|
40 /** Number of attempts to try restart the server after premature termination. */ |
|
41 const TInt KMaxTimesToRestartServer = 3; |
|
42 |
|
43 /** Maximum number of asynchronous IPC calls. */ |
|
44 const TInt KAsyncMessageSlots=6; |
|
45 |
|
46 |
|
47 /** |
|
48 Unlock the last locked contact item on the server. Used by OpenLX(). If any |
|
49 method which locks a contact item leaves thenccnt this method is called as the |
|
50 cleanup stack unwinds, removing the lock for the last locked contact item. |
|
51 |
|
52 @capability None |
|
53 */ |
|
54 void CleanupUnlockRecord(TAny *aSession) |
|
55 { |
|
56 static_cast<RCntModel*>(aSession)->UnlockLastLockedContact(); |
|
57 } |
|
58 |
|
59 |
|
60 /** |
|
61 Unlock the last locked contact item on the server. Used by OpenLX(). |
|
62 |
|
63 @capability None |
|
64 */ |
|
65 void RCntModel::UnlockLastLockedContact() |
|
66 { |
|
67 CloseContact(KNullContactId); |
|
68 } |
|
69 |
|
70 |
|
71 /** |
|
72 Push a Contact item unlock cleanup item on the cleanup stack. |
|
73 */ |
|
74 void RCntModel::PushUnlockL() const |
|
75 { |
|
76 CleanupStack::PushL( TCleanupItem(CleanupUnlockRecord, const_cast<RCntModel *>(this))); |
|
77 } |
|
78 |
|
79 |
|
80 /** |
|
81 RCntModel constructor. |
|
82 |
|
83 Member variables must be initialised (zero'd) in the constructor since |
|
84 RCntModel does not derive from CBase. |
|
85 */ |
|
86 RCntModel::RCntModel() |
|
87 : |
|
88 iDbNotifyMonitor(NULL), |
|
89 iPackager(NULL), |
|
90 iConnectionId(0), |
|
91 iNoOfSvrStartAttempts(0) |
|
92 { |
|
93 } |
|
94 |
|
95 |
|
96 /** |
|
97 Get the Contacts server version number. |
|
98 |
|
99 @return Contacts server version number. |
|
100 */ |
|
101 TVersion RCntModel::Version() const |
|
102 { |
|
103 return(TVersion(KCntServerMajorVersionNumber,KCntServerMinorVersionNumber,KCntServerBuildVersionNumber)); |
|
104 } |
|
105 |
|
106 |
|
107 /** Name of the executable for the Contacts server. */ |
|
108 _LIT(KCntServerExe,"CNTSRV.EXE"); |
|
109 /** Name used to connect a session to the Contacts server. */ |
|
110 _LIT(KCntServerName,"CNTSRV"); |
|
111 |
|
112 |
|
113 /** |
|
114 Open a Contacts server session. |
|
115 */ |
|
116 void RCntModel::ConnectL() |
|
117 { |
|
118 // Assume the server is already running and attempt to create a session |
|
119 // with a maximum of KAsyncMessageSlots message slots. |
|
120 TInt err = CreateSession(KCntServerName,Version(),KAsyncMessageSlots); |
|
121 |
|
122 if(err == KErrNotFound) // Server not running? |
|
123 { |
|
124 // Use the RProcess API to start the server. |
|
125 RProcess server; |
|
126 User::LeaveIfError(server.Create(KCntServerExe,KNullDesC)); |
|
127 |
|
128 //Enforce server to be at system default priority EPriorityForeground |
|
129 //Contact server used to set as EPriorityHigh and this caused client could |
|
130 //not get control or responsive until sorting by the idle sorter in remote |
|
131 //view was done. |
|
132 server.SetPriority(EPriorityForeground); |
|
133 |
|
134 // Synchronise with the server. |
|
135 TRequestStatus reqStatus; |
|
136 server.Rendezvous(reqStatus); |
|
137 server.Resume(); |
|
138 |
|
139 // Server will call the reciprocal static synchronisation call. |
|
140 User::WaitForRequest(reqStatus); |
|
141 server.Close(); |
|
142 User::LeaveIfError(reqStatus.Int()); |
|
143 |
|
144 // Create the server session. |
|
145 User::LeaveIfError(CreateSession(KCntServerName,Version(),KAsyncMessageSlots)); |
|
146 } |
|
147 else |
|
148 { |
|
149 User::LeaveIfError(err); |
|
150 } |
|
151 |
|
152 // Create object packer/unpacker if it doesn't already exist. |
|
153 if (iPackager == NULL) |
|
154 { |
|
155 iPackager = CCntPackager::NewL(); |
|
156 } |
|
157 |
|
158 // Each session (client) will be given a unique ID known as the Connection |
|
159 // ID. This ID forms part of the database event notification message. This |
|
160 // ID is created during the connection to the server. |
|
161 ConnectionId(); |
|
162 } |
|
163 |
|
164 |
|
165 /** |
|
166 Close session. |
|
167 */ |
|
168 void RCntModel::Close() |
|
169 { |
|
170 delete iPackager; |
|
171 iPackager = NULL; |
|
172 delete iDbNotifyMonitor; |
|
173 iDbNotifyMonitor = NULL; |
|
174 RHandleBase::Close(); |
|
175 } |
|
176 |
|
177 |
|
178 /** |
|
179 Open a named contact database. |
|
180 |
|
181 Opens the default contacts database if the default argument is used. The given |
|
182 descriptor must not contain more than KCntMaxFilePath characters. |
|
183 |
|
184 @param aCntFile Filename (in the form drive:database). Defaults to |
|
185 KCntDefaultDrive. |
|
186 |
|
187 @return KErrNone if success, KErrArgument if the given descriptor contains more than the |
|
188 maximum length of 190 characters, otherwise one of the System error codes. |
|
189 |
|
190 @capability ReadUserData |
|
191 */ |
|
192 TInt RCntModel::OpenDatabase(const TDesC& aCntFile) const |
|
193 { |
|
194 TInt err = SetFileName(aCntFile); |
|
195 if (err == KErrNone) |
|
196 { |
|
197 TIpcArgs args; |
|
198 args.Set(0,&aCntFile); |
|
199 err = SendReceive(ECntOpenDataBase, args); |
|
200 } |
|
201 |
|
202 return err; |
|
203 } |
|
204 |
|
205 |
|
206 /** |
|
207 Open a named contact database asynchronously. |
|
208 |
|
209 Opens the default contacts database if the default argument is used. The given |
|
210 descriptor must not contain more than KCntMaxFilePath characters. |
|
211 |
|
212 @param aStatus Asynchronous request object. Request is completed when database |
|
213 has been opened. |
|
214 @param aCntFile Contacts database filename (in the form drive:database). |
|
215 Defaults to KCntDefaultDrive. |
|
216 |
|
217 @capability ReadUserData |
|
218 */ |
|
219 void RCntModel::OpenDatabaseAsyncL(TRequestStatus& aStatus, const TDesC& aCntFile) |
|
220 { |
|
221 User::LeaveIfError(SetFileName(aCntFile)); |
|
222 |
|
223 TIpcArgs args; |
|
224 args.Set(0,&aCntFile); |
|
225 SendReceive(ECntOpenDataBase, args, aStatus); |
|
226 } |
|
227 |
|
228 |
|
229 /** |
|
230 Cancel last asynchronous database open request. |
|
231 |
|
232 @capability None |
|
233 */ |
|
234 void RCntModel::CancelAsyncOpen() |
|
235 { |
|
236 SendReceive(ECntCancelAsyncOpenDatabase); |
|
237 } |
|
238 |
|
239 |
|
240 /** |
|
241 Handle a premature termination of the contact server process by re-connecting |
|
242 the session and re-opening the database. |
|
243 |
|
244 @capability ReadUserData |
|
245 */ |
|
246 void RCntModel::HandlePrematureServerTerminationL() |
|
247 { |
|
248 if (iNoOfSvrStartAttempts > KMaxTimesToRestartServer) |
|
249 { |
|
250 User::Leave(KErrServerTerminated); |
|
251 } |
|
252 ConnectL(); |
|
253 User::LeaveIfError(OpenDatabase(iFileName)); |
|
254 ++iNoOfSvrStartAttempts; |
|
255 } |
|
256 |
|
257 |
|
258 /** |
|
259 Set the database filename. Used to re-open the database if the server is |
|
260 terminated prematurely. |
|
261 |
|
262 @param aCntFile Contacts database filename (in the form drive:database). |
|
263 @return KErrNone if success, KErrArgument if the given descriptor contains more than the |
|
264 maximum length of 190 characters. |
|
265 */ |
|
266 TInt RCntModel::SetFileName(const TDesC& aCntFile) const |
|
267 { |
|
268 if(aCntFile.Length() > KCntMaxFilePath) |
|
269 { |
|
270 return KErrArgument; |
|
271 } |
|
272 |
|
273 iFileName = aCntFile; |
|
274 return KErrNone; |
|
275 } |
|
276 |
|
277 |
|
278 /** |
|
279 Close currently open database. |
|
280 |
|
281 @capability None |
|
282 */ |
|
283 void RCntModel::CloseDatabase() const |
|
284 { |
|
285 (void)SendReceive(ECntCloseDataBase); |
|
286 } |
|
287 |
|
288 |
|
289 /** |
|
290 Get the machine ID. |
|
291 |
|
292 Note: This function can leave. |
|
293 |
|
294 @return Machine ID. |
|
295 |
|
296 @leave KErrNone The send operation is successful |
|
297 @leave KErrServerTerminated The server no longer present |
|
298 @leave KErrServerBusy There are no message slots available |
|
299 @leave KErrNoMemory There is insufficient memory available |
|
300 |
|
301 |
|
302 @capability None |
|
303 */ |
|
304 TInt64 RCntModel::MachineId() const |
|
305 { |
|
306 TIpcArgs args; |
|
307 TPckgBuf<TInt64> machineID; |
|
308 args.Set(0, &machineID); |
|
309 User::LeaveIfError(SendReceive(ECntMachineID, args)); // this can leave |
|
310 return machineID(); |
|
311 } |
|
312 |
|
313 |
|
314 /** |
|
315 Set the machine ID (debug only). |
|
316 |
|
317 @param aMachineUniqueId New machine ID. |
|
318 |
|
319 @capability None |
|
320 */ |
|
321 void RCntModel::OverrideMachineUniqueId(TInt64 aMachineUniqueId) |
|
322 { |
|
323 TIpcArgs args; |
|
324 TPckgBuf<TInt64> machineID(aMachineUniqueId); |
|
325 args.Set(0, &machineID); |
|
326 (void)SendReceive(ECntOverrideMachineID, args); |
|
327 } |
|
328 |
|
329 |
|
330 /** |
|
331 Replace a named contact database with an empty one, replacing any database with |
|
332 the same name. Replaces the default contacts database if the default argument |
|
333 is used. The given descriptor must not contain more than KCntMaxFilePath |
|
334 characters. |
|
335 |
|
336 @param aCntFile Contacts database filename (in the form drive:database). |
|
337 Defaults to KCntDefaultDrive. |
|
338 |
|
339 @return KErrNone if success, KErrArgument if the given descriptor contains more than the |
|
340 maximum length of 190 characters, KErrInUse if the database is currently open, |
|
341 otherwise one of the System error codes. |
|
342 |
|
343 @capability WriteUserData |
|
344 */ |
|
345 TInt RCntModel::ReplaceDatabase(const TDesC& aCntFile) const |
|
346 { |
|
347 TInt err = SetFileName(aCntFile); |
|
348 if (err == KErrNone) |
|
349 { |
|
350 TIpcArgs args; |
|
351 args.Set(0,&aCntFile); |
|
352 |
|
353 err = SendReceive(ECntReplaceDatabase, args); |
|
354 } |
|
355 |
|
356 return err; |
|
357 } |
|
358 |
|
359 |
|
360 /** |
|
361 Returns an array of contact item IDs for all the contact items which may contain |
|
362 the specified telephone number in a telephone, fax or SMS type field. |
|
363 |
|
364 @see CContactDatabase::MatchPhoneNumberL() for more details on the match. |
|
365 |
|
366 @param aNumber Phone number string |
|
367 @param aMatchLengthFromRight Number of digits from the right of the phone number |
|
368 to use. Up to 15 digits can be specified and it is recommended that at least 7 |
|
369 match digits are specified. |
|
370 |
|
371 @return CContactIdArray of candidate matches. |
|
372 |
|
373 @capability ReadUserData |
|
374 */ |
|
375 CContactIdArray* RCntModel::MatchPhoneNumberL(const TDesC& aNumber, const TInt aMatchLengthFromRight) |
|
376 { |
|
377 TIpcArgs args; |
|
378 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
379 args.Set(1, MLplCollection::EMatchPhoneNos); |
|
380 args.Set(2, &aNumber); |
|
381 args.Set(3, aMatchLengthFromRight); |
|
382 |
|
383 TInt newBuffSize = 0; |
|
384 User::LeaveIfError(newBuffSize = SendReceive(ECntGetCollection, args)); |
|
385 |
|
386 if (newBuffSize > 0) |
|
387 { |
|
388 // If the buffer is not large enough resize the packager's internal |
|
389 // buffer and make the call again. |
|
390 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
391 User::LeaveIfError(newBuffSize = SendReceive(ECntGetCollection, args)); |
|
392 } |
|
393 |
|
394 CContactIdArray* idArray = iPackager->UnpackCntIdArrayLC(); |
|
395 CleanupStack::Pop(idArray); |
|
396 |
|
397 return idArray; |
|
398 } |
|
399 |
|
400 |
|
401 |
|
402 /** |
|
403 Create an empty named contact database. |
|
404 |
|
405 Creates the default contacts database if the default argument is used. The |
|
406 given descriptor must not contain more than KCntMaxFilePath characters. |
|
407 |
|
408 @param aCntFile Contacts database filename (in the form drive:database). |
|
409 Defaults to KCntDefaultDrive. |
|
410 |
|
411 @return KErrNone if success, KErrArgument if the given descriptor contains more than the |
|
412 maximum length of 190 characters, KErrAlreadyExists if the database already |
|
413 exists otherwise one of the System error codes. |
|
414 |
|
415 @capability WriteUserData |
|
416 */ |
|
417 TInt RCntModel::CreateDatabase(const TDesC& aCntFile) const |
|
418 { |
|
419 TInt err = SetFileName(aCntFile); |
|
420 if (err == KErrNone) |
|
421 { |
|
422 TIpcArgs args; |
|
423 args.Set(0,&aCntFile); |
|
424 err = SendReceive(ECntCreateDatabase, args); |
|
425 } |
|
426 return err; |
|
427 } |
|
428 |
|
429 |
|
430 /** |
|
431 Create the system template. |
|
432 |
|
433 @return KErrNone if success otherwise one of the System error codes. |
|
434 |
|
435 @capability WriteUserData |
|
436 */ |
|
437 TInt RCntModel::ReCreateTemplate() const |
|
438 { |
|
439 return SendReceive(ECntReCreateTemplate); |
|
440 } |
|
441 |
|
442 |
|
443 /** |
|
444 Get the database file UID. |
|
445 |
|
446 @return Pointer to file UID. |
|
447 |
|
448 @capability None |
|
449 */ |
|
450 TPtrC RCntModel::FileUidL() const |
|
451 { |
|
452 TIpcArgs args; |
|
453 args.Set(0, &iFileUid); |
|
454 User::LeaveIfError (SendReceive(ECntFileUniqueId, args)); |
|
455 return iFileUid; |
|
456 } |
|
457 |
|
458 |
|
459 /** |
|
460 Determine if the database is ready. Ready in this context means that the |
|
461 database is open and readable/writable (i.e. the state machine is in |
|
462 CStateWritable). |
|
463 |
|
464 @capability None |
|
465 |
|
466 @return ETrue if the database is ready, EFalse if the database is not ready. |
|
467 */ |
|
468 TBool RCntModel::DatabaseReadyL() const |
|
469 { |
|
470 TBool retVal = EFalse; |
|
471 |
|
472 // Although the ECntGetDatabaseReady msg. is completed with TBool values, |
|
473 // during message processing, it is possible that ServiceError() occurs, |
|
474 // causing the message to be completed with negative error codes. |
|
475 // LeaveIfError() would protect against such cases. |
|
476 User::LeaveIfError(retVal = SendReceive(ECntGetDatabaseReady)); |
|
477 |
|
478 return retVal; |
|
479 } |
|
480 |
|
481 |
|
482 /** |
|
483 Tests whether a contact item's hint bit field matches a filter. |
|
484 |
|
485 @param aBitWiseFilter The filter to compare the item against. This is a |
|
486 combination of TContactViewFilter values. |
|
487 @param aContactId The ID of the item in the database. |
|
488 |
|
489 @return ETrue if the item is of the correct type for inclusion in the database |
|
490 and its hint bit field matches the specified filter, EFalse if either of these |
|
491 conditions are not met. |
|
492 |
|
493 @capability None |
|
494 */ |
|
495 TBool RCntModel::ContactMatchesHintFieldL(TInt aBitWiseFilter, TContactItemId aContactId) |
|
496 { |
|
497 TIpcArgs args; |
|
498 args.Set(0, aBitWiseFilter); |
|
499 args.Set(1, aContactId); |
|
500 TBool retVal = EFalse; |
|
501 |
|
502 // Although the ECntMatchesHintField msg. is completed with TBool values, |
|
503 // during message processing, it is possible that ServiceError() occurs, |
|
504 // causing the message to be completed with negative error codes. |
|
505 // LeaveIfError() would protect against such cases. |
|
506 User::LeaveIfError (retVal = SendReceive(ECntMatchesHintField, args)); |
|
507 |
|
508 return retVal; |
|
509 } |
|
510 |
|
511 |
|
512 /** |
|
513 Delete a named contact database. |
|
514 |
|
515 Deletes the default contacts database if the default argument is used. The |
|
516 given descriptor must not contain more than KCntMaxFilePath characters. |
|
517 |
|
518 @param aCntFile Contacts database filename (in the form drive:database). |
|
519 Defaults to KCntDefaultDrive. |
|
520 |
|
521 @return KErrNone if success, KErrArgument if the given descriptor contains more |
|
522 than the maximum length of 190 characters, KErrInUse if the database is |
|
523 in use, KErrNotFound if the database does not exist otherwise one of the |
|
524 System error codes. |
|
525 |
|
526 @capability WriteUserData |
|
527 */ |
|
528 TInt RCntModel::DeleteDatabase(const TDesC& aCntFile) const |
|
529 { |
|
530 if(aCntFile.Length() > KCntMaxFilePath) |
|
531 { |
|
532 return KErrArgument; |
|
533 } |
|
534 TIpcArgs args; |
|
535 args.Set(0,&aCntFile); |
|
536 return SendReceive(ECntDeleteDatabase,args); |
|
537 } |
|
538 |
|
539 |
|
540 /** |
|
541 Get the name of the default contact database file. |
|
542 |
|
543 The given descriptor must have room for minimum of KCntMaxFilePath characters. |
|
544 |
|
545 @param aCntFile Contains the default contact database name on return. |
|
546 |
|
547 @return KErrNone if success, KErrArgument if the given descriptor contains more |
|
548 than the maximum length of 190 characters, otherwise one of the System |
|
549 error codes. |
|
550 |
|
551 @capability None |
|
552 */ |
|
553 TInt RCntModel::DefaultDatabase(TDes& aCntFile) const |
|
554 { |
|
555 TIpcArgs args; |
|
556 args.Set(0,&aCntFile); |
|
557 return SendReceive(ECntGetDefaultDatabaseName,args); |
|
558 } |
|
559 |
|
560 |
|
561 /** |
|
562 Retrieve the current contact database drive. |
|
563 |
|
564 @param aDriveUnit Contains the current contact database drive unit on return. |
|
565 |
|
566 @return KErrNone if success otherwise one of the System error codes. |
|
567 |
|
568 @capability None |
|
569 */ |
|
570 TInt RCntModel::DatabaseDrive(TDriveUnit& aDriveUnit) const |
|
571 { |
|
572 TInt ret = SendReceive(ECntDatabaseDrive); |
|
573 if (ret >= KErrNone) |
|
574 { |
|
575 aDriveUnit = ret; |
|
576 } |
|
577 return ret; |
|
578 } |
|
579 |
|
580 |
|
581 /** |
|
582 Sets the contact database drive and optionally moves the default contact |
|
583 database from its current location to the new drive. This function guarantees |
|
584 an all or nothing operation. If the database is not successfully moved, the |
|
585 drive setting is not updated to reflect the change. |
|
586 |
|
587 @param aDriveUnit The drive to which to move the contact database. |
|
588 @param aCopy ETrue moves the existing file to the specified drive. Deletion of |
|
589 the source file will fail if it is in use. EFalse does not move the file. The |
|
590 default argument value is ETrue. |
|
591 |
|
592 @return KErrNone if success, KErrInUse if destination file for copy is open, |
|
593 KErrNotFound found if source contact database (default) cannot be found, |
|
594 KErrAlreadyExists if the destination contact database file exists. |
|
595 |
|
596 @capability WriteUserData |
|
597 */ |
|
598 void RCntModel::SetDatabaseDriveL(TDriveUnit aDriveUnit, TBool aCopy) |
|
599 { |
|
600 TIpcArgs args; |
|
601 args.Set(0,aDriveUnit); |
|
602 args.Set(1,aCopy); |
|
603 User::LeaveIfError(SendReceive(ECntSetDatabaseDrive,args)); |
|
604 } |
|
605 |
|
606 /** |
|
607 Gets the size of the database file in bytes. |
|
608 |
|
609 @return The size of the contact database in bytes. |
|
610 |
|
611 @capability None |
|
612 */ |
|
613 TInt RCntModel::FileSize() const |
|
614 { |
|
615 return SendReceive(ECntFilesSize); |
|
616 } |
|
617 |
|
618 /** |
|
619 Determine if the named contact database file exists. |
|
620 |
|
621 If the aCntFile argument is the default, determines if default contact database |
|
622 file exists. |
|
623 |
|
624 @param aCntFile Contacts database filename (in the form drive:database). |
|
625 @leave KErrArgument if the given descriptor contains more than the maximum length |
|
626 of 190 characters, otherwise one of the System error codes. |
|
627 @return ETrue if exists, EFalse does not exist. |
|
628 @capability None |
|
629 */ |
|
630 TBool RCntModel::DatabaseExistsL(const TDesC& aCntFile) const |
|
631 { |
|
632 if(aCntFile.Length() > KCntMaxFilePath) |
|
633 { |
|
634 User::Leave(KErrArgument); |
|
635 } |
|
636 |
|
637 TIpcArgs args; |
|
638 args.Set(0,&aCntFile); |
|
639 TBool ret = EFalse; |
|
640 |
|
641 // Although ECntDatabaseExists is normally completed with TBool values, |
|
642 // ServiceError() can occur which leads to a negative system error codes |
|
643 // being returned. User::LeaveIfError will allow that to be properly handled. |
|
644 User::LeaveIfError(ret = SendReceive(ECntDatabaseExists,args)); |
|
645 |
|
646 return ret; |
|
647 } |
|
648 |
|
649 |
|
650 /** |
|
651 List the contact database files for any given drive unit. Lists all databases |
|
652 on all drives if aDriveUnit is set to NULL. |
|
653 |
|
654 @param aDriveUnit The drive unit to search. Searches all drives if default |
|
655 argument is used. |
|
656 |
|
657 @return CDesCArray containing the database list. Always returns list even if |
|
658 empty. |
|
659 |
|
660 @leave KErrNoMemory if not enough free memory, KErrNotReady if drive does not, |
|
661 otherwise one of the System error codes. |
|
662 |
|
663 @capability ReadUserData |
|
664 */ |
|
665 CDesCArray* RCntModel::ListDatabasesL(TDriveUnit* aDriveUnit) const |
|
666 { |
|
667 // Convert the drive unit to an integer for IPC. The TDriveUnit constructor |
|
668 // does not allow values outside 0 - 25. |
|
669 TInt driveNumber; |
|
670 (aDriveUnit == NULL) ? (driveNumber = ECntAllDrives) : (driveNumber = *aDriveUnit); |
|
671 |
|
672 // Provide a CBufFlat for receiving the list of databases from the server. |
|
673 // Format is a (proprietary) serialized CDesCArray. |
|
674 const TInt KInitialBufferSize = 200; |
|
675 CBufFlat* listBuffer = CBufFlat::NewL(KInitialBufferSize); |
|
676 CleanupStack::PushL(listBuffer); |
|
677 listBuffer->ExpandL(0,KInitialBufferSize); |
|
678 |
|
679 // IPC argument list is: |
|
680 // 0 (Return param) - Address of our receive buffer |
|
681 // 1 (Param) - The drive number 0 - 25 or ECntAllDrives |
|
682 // 2 (Return param) - The size of buffer required for the transfer |
|
683 TIpcArgs args; |
|
684 TPtr8 ptr(listBuffer->Ptr(0)); |
|
685 args.Set(0,&ptr); |
|
686 args.Set(1,driveNumber); |
|
687 TPckgBuf<TInt> size; |
|
688 args.Set(2,&size); |
|
689 User::LeaveIfError(SendReceive(ECntListDatabases,args)); |
|
690 |
|
691 // Check if our buffer was large enough by reading returned size argument. |
|
692 // The server will not have written any data if our povided buffer was not |
|
693 // big enough. |
|
694 if(size() > KInitialBufferSize) |
|
695 { |
|
696 // Not big enough but now we know how big the buffer needs to be. |
|
697 // Just allocate buffer again, reset the IPC args and call again. |
|
698 CleanupStack::PopAndDestroy(listBuffer); |
|
699 listBuffer = CBufFlat::NewL(size()); |
|
700 CleanupStack::PushL(listBuffer); |
|
701 listBuffer->ExpandL(0,size()); |
|
702 ptr.Set(listBuffer->Ptr(0)); |
|
703 args.Set(0,&ptr); |
|
704 args.Set(1,driveNumber); |
|
705 args.Set(2,&size); |
|
706 User::LeaveIfError(SendReceive(ECntListDatabases,args)); |
|
707 } |
|
708 |
|
709 // Wrap the buffer in a read stream class to internalize. |
|
710 RBufReadStream readStream; |
|
711 readStream.Open(*listBuffer); |
|
712 CleanupClosePushL(readStream); |
|
713 |
|
714 // Number of array elements. |
|
715 const TInt count = readStream.ReadUint32L(); |
|
716 // Use count if it is not zero. |
|
717 CDesCArray* list = new(ELeave) CDesCArrayFlat(count ? count : 1); |
|
718 CleanupStack::PushL(list); |
|
719 for (TInt i=0; i<count; ++i) |
|
720 { |
|
721 TFileName path; |
|
722 TInt length=readStream.ReadInt8L(); |
|
723 readStream.ReadL(path,length); |
|
724 // Add to the list. |
|
725 list->AppendL(path); |
|
726 } |
|
727 |
|
728 CleanupStack::Pop(list); |
|
729 CleanupStack::PopAndDestroy(&readStream); |
|
730 CleanupStack::PopAndDestroy(listBuffer); |
|
731 |
|
732 return list; |
|
733 } |
|
734 |
|
735 |
|
736 /** |
|
737 Add a new contact to the database. |
|
738 |
|
739 @param aContact The contact to be added to the database. |
|
740 |
|
741 @capability WriteUserData |
|
742 */ |
|
743 TContactItemId RCntModel::CreateContactL(CContactItem& aContact) const |
|
744 { |
|
745 // Pack the contact into the first IPC argument. |
|
746 TIpcArgs args; |
|
747 TPtr8 ptr(iPackager->PackL(aContact)); |
|
748 args.Set(0,&ptr); |
|
749 |
|
750 TInt cntId = 0; |
|
751 User::LeaveIfError(cntId = SendReceive(ECntItemCreate, args)); |
|
752 |
|
753 return cntId; |
|
754 } |
|
755 |
|
756 |
|
757 /** |
|
758 Delete a contact from the database. |
|
759 |
|
760 @param aContact The contact to be deleted. |
|
761 @param aCntEventType The event type to pass on to the observers. |
|
762 @param aDecAccessCount If ETrue access count should be decremented prior to the |
|
763 deletion. |
|
764 |
|
765 @capability WriteUserData |
|
766 */ |
|
767 void RCntModel::DeleteContactL(TContactItemId aCntId, TCntSendEventAction aCntEventType, TBool aDecAccessCount) const |
|
768 { |
|
769 TIpcArgs args(aCntId, aCntEventType, aDecAccessCount); |
|
770 User::LeaveIfError(SendReceive(ECntItemDelete, args)); |
|
771 } |
|
772 |
|
773 /** |
|
774 Open the database tables. |
|
775 |
|
776 @capability ReadUserData |
|
777 */ |
|
778 void RCntModel::OpenTablesL() |
|
779 { |
|
780 User::LeaveIfError(SendReceive(ECntReOpenDbTables)); |
|
781 } |
|
782 |
|
783 |
|
784 /** |
|
785 Close the database tables. |
|
786 |
|
787 @capability None |
|
788 */ |
|
789 void RCntModel::CloseTablesL() |
|
790 { |
|
791 User::LeaveIfError(SendReceive(ECntCloseDbTables)); |
|
792 } |
|
793 |
|
794 |
|
795 /** |
|
796 Update and unlock an existing contact in the database. |
|
797 |
|
798 @param aContact The contact to be updated and unlocked |
|
799 @param aSendChangedEvent If ETrue the changed event should be sent after the |
|
800 update/unlock. |
|
801 |
|
802 @capability WriteUserData |
|
803 */ |
|
804 void RCntModel::CommitContactL(const CContactItem& aContact, TBool aSendChangedEvent) const |
|
805 { |
|
806 // Pack the contact into the first IPC argument. |
|
807 TIpcArgs args; |
|
808 TPtr8 ptr(iPackager->PackL((const_cast<CContactItem&>(aContact)))); |
|
809 args.Set(0,&ptr); |
|
810 |
|
811 args.Set(1,aSendChangedEvent); |
|
812 |
|
813 User::LeaveIfError(SendReceive(ECntItemCommit, args)); |
|
814 } |
|
815 |
|
816 |
|
817 /** |
|
818 Unpacks a contact item contained within the Packager's internal buffer and |
|
819 creates a contact item object. Within the server, the contact item has been |
|
820 written to the Packager's internal buffer by the RMessage2. |
|
821 |
|
822 If the buffer size was returned then the buffer was not large enough to hold a |
|
823 serialised contact item. The buffer must be expanded to the size returned by |
|
824 the server (ie aBufferSize) and the read operation performed again. |
|
825 |
|
826 @see CCntPackager::SetBufferFromMessageL() |
|
827 |
|
828 @param aBufferSize The new buffer size. |
|
829 @param aArgs The argument buffer where the serialised contact item is written by |
|
830 the server. |
|
831 |
|
832 @return CContactItem unpacked from Packager's internal buffer. |
|
833 |
|
834 @capability ReadUserData |
|
835 */ |
|
836 CContactItem* RCntModel::UnPackContactLC(TInt aBufferSize, TIpcArgs& aArgs) const |
|
837 { |
|
838 if(aBufferSize > 0) // Packager's internal buffer is not large enough. |
|
839 { |
|
840 // Set new extended receiving buffer. |
|
841 aArgs.Set(1, &iPackager->GetReceivingBufferL(aBufferSize)); |
|
842 // Perform read operation again. |
|
843 User::LeaveIfError(SendReceive(ECntItemRead, aArgs)); |
|
844 } |
|
845 return iPackager->UnpackCntItemLC(); |
|
846 } |
|
847 |
|
848 |
|
849 /** |
|
850 Read an existing contact in the database. |
|
851 |
|
852 @param aCntItemVDef The view definition to use. |
|
853 @param aCntId Contact ID to read. |
|
854 |
|
855 @return CContactItem object with contact ID aCntId. |
|
856 */ |
|
857 CContactItem* RCntModel::ReadContactL(const CContactItemViewDef* aCntItemVDef, TContactItemId aCntId) const |
|
858 { |
|
859 TIpcArgs args; |
|
860 |
|
861 if (aCntItemVDef) |
|
862 { |
|
863 iPackager->PackL(*(const_cast<CContactItemViewDef*>(aCntItemVDef))); |
|
864 // Indicates that a user ContactItemViewDef is present in first IPC |
|
865 // argument. |
|
866 args.Set(3,TRUE); |
|
867 } |
|
868 else |
|
869 { |
|
870 iPackager->Clear(); |
|
871 // Indicates that no user ContactItemViewDef is present in first IPC |
|
872 // argument. The default view definition will be used instead. |
|
873 args.Set(3,FALSE); |
|
874 } |
|
875 |
|
876 args.Set(0, &iPackager->GetTransmittingBuffer()); |
|
877 args.Set(1, &iPackager->GetReceivingBufferL()); |
|
878 args.Set(2, aCntId); |
|
879 |
|
880 TInt newBuffSize = 0; |
|
881 User::LeaveIfError(newBuffSize = SendReceive(ECntItemRead, args)); |
|
882 CContactItem* cntItem = UnPackContactLC(newBuffSize, args); |
|
883 CleanupStack::Pop(cntItem); |
|
884 |
|
885 return cntItem; |
|
886 } |
|
887 |
|
888 |
|
889 /** |
|
890 Open and lock an existing contact in the database. The contact item lock is |
|
891 pushed onto the cleanup stack. |
|
892 |
|
893 @param aCntItemVDef The view definition to use. |
|
894 @param aCntId Contact ID to read. |
|
895 |
|
896 @return Opened/locked CContactItem object. |
|
897 */ |
|
898 CContactItem* RCntModel::OpenContactLX(const CContactItemViewDef* aCntItemVDef, TContactItemId aCntId) const |
|
899 { |
|
900 TIpcArgs args; |
|
901 if (aCntItemVDef) |
|
902 { |
|
903 iPackager->PackL(*(const_cast<CContactItemViewDef*>(aCntItemVDef))); |
|
904 // Indicates that a user ContactItemViewDef is present in first IPC |
|
905 // argument. |
|
906 args.Set(3,TRUE); |
|
907 } |
|
908 else |
|
909 { |
|
910 iPackager->Clear(); |
|
911 // Indicates that no user ContactItemViewDef is present in first IPC |
|
912 // argument. The default view definition will be used instead. |
|
913 args.Set(3,FALSE); |
|
914 } |
|
915 |
|
916 args.Set(0, &iPackager->GetTransmittingBuffer()); |
|
917 args.Set(1, &iPackager->GetReceivingBufferL()); |
|
918 args.Set(2, aCntId); |
|
919 |
|
920 TInt newBuffSize = 0; |
|
921 User::LeaveIfError(newBuffSize = SendReceive(ECntItemOpen, args)); |
|
922 |
|
923 // Push the contact item lock onto the cleanup stack. If UnPackContactLC() |
|
924 // (or any other RCntModel method leaves after this point) then the last |
|
925 // contact to be locked will be unlocked (aka closed). The method returns |
|
926 // with the lock remaining on the cleanup stack. |
|
927 PushUnlockL(); |
|
928 |
|
929 CContactItem* cntItem = UnPackContactLC(newBuffSize, args); |
|
930 |
|
931 CleanupStack::Pop(cntItem); |
|
932 |
|
933 return cntItem; |
|
934 } |
|
935 |
|
936 |
|
937 /** |
|
938 Close/unLock an existing contact in the database. |
|
939 |
|
940 @param aCntId The contact ID of the contact to close. |
|
941 |
|
942 @return ETrue if the contact was opened before and closed after the call, |
|
943 EFalse if there was no need to close the contact. |
|
944 */ |
|
945 TBool RCntModel::CloseContact(TContactItemId aCntId) |
|
946 { |
|
947 TInt res = SendReceive(ECntItemClose, TIpcArgs(aCntId)); |
|
948 if (res == KErrNone) |
|
949 { |
|
950 return ETrue; |
|
951 } |
|
952 return EFalse; |
|
953 } |
|
954 |
|
955 |
|
956 /** |
|
957 Start a database transaction. |
|
958 */ |
|
959 TInt RCntModel::BeginDbTransaction() const |
|
960 { |
|
961 return SendReceive(EBeginDbTransaction); |
|
962 } |
|
963 |
|
964 |
|
965 /** |
|
966 Commit a database transaction. |
|
967 */ |
|
968 TInt RCntModel::CommitDbTransaction() const |
|
969 { |
|
970 return SendReceive(EEndDbTransaction); |
|
971 } |
|
972 |
|
973 |
|
974 /** |
|
975 Rollback a database transaction. |
|
976 */ |
|
977 TInt RCntModel::RollbackDbTransaction() const |
|
978 { |
|
979 return SendReceive(ERollbackDbTransaction); |
|
980 } |
|
981 |
|
982 |
|
983 /** |
|
984 Set the operation timeout value. This value is the length of time that a |
|
985 deferred request will remain in the request queue in the State Machine before |
|
986 being completed with an error code. |
|
987 |
|
988 @param aMicroSeconds The operation timeout in microseconds. This timeout will |
|
989 only be applied to requests sent by clients of this database after this point in |
|
990 time. |
|
991 */ |
|
992 void RCntModel::SetOperationTimeOutL(const TInt aMicroSeconds) const |
|
993 { |
|
994 TIpcArgs args; |
|
995 args.Set(0, aMicroSeconds); |
|
996 User::LeaveIfError(SendReceive(ECntOpsTimeOut, args)); |
|
997 } |
|
998 |
|
999 |
|
1000 /** |
|
1001 Change the existing contact view definition on the server. |
|
1002 |
|
1003 @param aView The new contact view defintion. |
|
1004 */ |
|
1005 void RCntModel::SetViewDefinitionL(const CContactViewDef& aView) |
|
1006 { |
|
1007 TPtr8 ptr(iPackager->PackL(aView)); |
|
1008 User::LeaveIfError(SendReceive(ECntChangeViewDef, TIpcArgs(&ptr))); |
|
1009 } |
|
1010 |
|
1011 |
|
1012 /** |
|
1013 Add a database event observer. |
|
1014 |
|
1015 @param aObserver Observer callback inteface used to send database event. |
|
1016 */ |
|
1017 void RCntModel::AddObserverL(MContactDbObserver& aObserver) |
|
1018 { |
|
1019 // If this is the first observer to be added then required to create the |
|
1020 // database event notification monitor (lazy initialisation). |
|
1021 if (!iDbNotifyMonitor) |
|
1022 { |
|
1023 iDbNotifyMonitor = CCntDbNotifyMonitor::NewL(*this); |
|
1024 } |
|
1025 iDbNotifyMonitor->AddObserverL(aObserver); |
|
1026 } |
|
1027 |
|
1028 |
|
1029 /** |
|
1030 Remove a database event observer. |
|
1031 |
|
1032 @param aObserver Observer callback inteface to be removed. |
|
1033 */ |
|
1034 void RCntModel::RemoveObserver(const MContactDbObserver& aObserver) |
|
1035 { |
|
1036 if (iDbNotifyMonitor) |
|
1037 { |
|
1038 iDbNotifyMonitor->RemoveObserver(aObserver); |
|
1039 // If this is the last observer to be removed then dispose of the |
|
1040 // database event notification monitor (no longer required). |
|
1041 if (iDbNotifyMonitor->NumberOfListeners() == 0) |
|
1042 { |
|
1043 delete iDbNotifyMonitor; |
|
1044 iDbNotifyMonitor = NULL; |
|
1045 } |
|
1046 } |
|
1047 } |
|
1048 |
|
1049 |
|
1050 /** |
|
1051 Request a database event from the server. |
|
1052 |
|
1053 @param aStatus Completed when database event is available. |
|
1054 @param aEvent When aStatus is completed contains the database event. |
|
1055 */ |
|
1056 void RCntModel::StartNotificationTransfer(TRequestStatus& aStatus, TDes8& aEvent) |
|
1057 { |
|
1058 SendReceive(ECntRequestEvent, TIpcArgs(&aEvent), aStatus); |
|
1059 } |
|
1060 |
|
1061 |
|
1062 /** |
|
1063 End (cancel) request for database event from server. |
|
1064 */ |
|
1065 void RCntModel::EndNotificationTransfer() |
|
1066 { |
|
1067 SendReceive(ECntCancelEventRequest); |
|
1068 } |
|
1069 |
|
1070 /** |
|
1071 Sets the ID of the current item and persists it in the database. The current |
|
1072 item is provided for use by clients who want to identify one contact item in the |
|
1073 database as the currently selected item. |
|
1074 |
|
1075 @param aContactId The ID of the current item. |
|
1076 |
|
1077 @capability WriteUserData |
|
1078 */ |
|
1079 void RCntModel::SetCurrentItem(TContactItemId aContactId) const |
|
1080 { |
|
1081 TIpcArgs args(aContactId); |
|
1082 (void)SendReceive(ECntSetCurrentItem, args); |
|
1083 } |
|
1084 |
|
1085 |
|
1086 /** |
|
1087 Gets the ID of the current item, as set by SetCurrentItem(). The current item |
|
1088 ID is initialised to KNullContactId when the database is opened. |
|
1089 |
|
1090 @return The ID of the current item. |
|
1091 |
|
1092 @capability None |
|
1093 */ |
|
1094 TContactItemId RCntModel::CurrentItem() const |
|
1095 { |
|
1096 TContactItemId id = SendReceive(ECntGetCurrentItem); |
|
1097 if (id < 0) |
|
1098 { |
|
1099 return KNullContactId; |
|
1100 } |
|
1101 else |
|
1102 { |
|
1103 return id; |
|
1104 } |
|
1105 } |
|
1106 |
|
1107 |
|
1108 /** |
|
1109 When there are multiple contact databases on a device this method can be used to |
|
1110 enquire which database is the current one. |
|
1111 |
|
1112 The current database functions are provided as part of current item |
|
1113 functionality. In order to pass a current item from one contacts model client |
|
1114 to another, the receiving client needs to be using the same database. |
|
1115 |
|
1116 The current database is a path and filename, set using SetCurrentDatabase(), |
|
1117 which is persisted by the contacts server. |
|
1118 |
|
1119 @deprecated |
|
1120 |
|
1121 @param aDatabase The path and filename of the current database. KNullDesC |
|
1122 if no current database has been set. |
|
1123 |
|
1124 @return KErrNone if success otherwise one of the System error codes. |
|
1125 |
|
1126 @capability None |
|
1127 */ |
|
1128 TInt RCntModel::GetCurrentDatabase(TDes& aDatabase) const |
|
1129 { |
|
1130 TIpcArgs args(&aDatabase); |
|
1131 return SendReceive(ECntGetCurrentDb, args); |
|
1132 } |
|
1133 |
|
1134 |
|
1135 /** |
|
1136 When there are multiple contact databases on a device this method can be used to |
|
1137 set a database as the current one. |
|
1138 |
|
1139 Note: this function simply updates a file name which is stored by the Contacts |
|
1140 server and its use is optional. It is provided as part of current item |
|
1141 functionality. |
|
1142 |
|
1143 In order to pass a current item from one contacts model client to another, |
|
1144 the receiving client needs to be using the same database. |
|
1145 |
|
1146 @deprecated |
|
1147 |
|
1148 @param aDatabase The path and filename of the current database. |
|
1149 |
|
1150 @return KErrNone if success otherwise one of the System error codes. |
|
1151 |
|
1152 @capability WriteUserData |
|
1153 */ |
|
1154 TInt RCntModel::SetCurrentDatabase(const TDesC& aDatabase) const |
|
1155 { |
|
1156 TIpcArgs args(&aDatabase); |
|
1157 return SendReceive(ECntSetCurrentDb, args); |
|
1158 } |
|
1159 |
|
1160 |
|
1161 /** |
|
1162 Returns the ID of the contact item whose telephone number field is mapped to |
|
1163 the speed dial position specified. |
|
1164 |
|
1165 This function is provided so that information may be displayed about a contact |
|
1166 item whose telephone number is being dialled using speed dialling. |
|
1167 |
|
1168 The function also retrieves the telephone number stored in the field. |
|
1169 |
|
1170 @param aSpeedDialPosition The speed dial position. This is an integer in the |
|
1171 range 1 to 9 inclusive. If outside this range, the function leaves with |
|
1172 KErrArgument. |
|
1173 @param aPhoneNumber On return contains the telephone number which is mapped to |
|
1174 the speed dial position specified. Returns KNullDesC if the speed dial position |
|
1175 requested has not been set. |
|
1176 |
|
1177 @return The ID of the contact item to which the speed dial is mapped. |
|
1178 |
|
1179 @capability ReadUserData |
|
1180 */ |
|
1181 TContactItemId RCntModel::GetSpeedDialFieldL(TInt aSpeedDialPosition, TDes& aPhoneNumber) |
|
1182 { |
|
1183 __ASSERT_ALWAYS(aSpeedDialPosition >= KCntMinSpeedDialIndex && aSpeedDialPosition <= KCntMaxSpeedDialIndex , User::Leave(KErrArgument)); |
|
1184 TPckgBuf<TContactItemId> contact(KNullContactId); |
|
1185 TIpcArgs args(aSpeedDialPosition,&aPhoneNumber); |
|
1186 return (TContactItemId)SendReceive(ECntGetSpeedDialContactIdAndPhoneNumber, args); |
|
1187 } |
|
1188 |
|
1189 |
|
1190 /** |
|
1191 Sets a field containing a telephone number as a speed dial field. The field |
|
1192 is identified by aFieldIndex within the contact item aItem. It is assigned a |
|
1193 speed dial position between 1 and 9 inclusive. |
|
1194 |
|
1195 The field's speed dial and user added attributes are set and the appropriate |
|
1196 UID (KUidSpeedDialXxx) is added to the field's content type. The changes are |
|
1197 committed to the database. |
|
1198 |
|
1199 Notes: |
|
1200 |
|
1201 - If an item's telephone number field has already been assigned to position |
|
1202 aSpeedDialPosition, that item is updated so that the speed dial attribute |
|
1203 is removed from its field and the speed dial field type UID is removed from |
|
1204 the field's content type, before the new speed dial field is set. |
|
1205 |
|
1206 - The speed dial attribute can be tested for using the |
|
1207 CContactItemField::IsSpeedDial() method. |
|
1208 |
|
1209 - The contact item passed to this function (aItem) must have been obtained using |
|
1210 one of the variants of CContactDatabase::OpenContactL(). This is because it |
|
1211 is modified and committed to the database by this function - no further |
|
1212 commits are necessary. |
|
1213 |
|
1214 @param aItem The contact item containing the field to set as a speed dial |
|
1215 field. |
|
1216 @param aFieldIndex Index of a field in aItem's field set to set as a speed dial |
|
1217 field. |
|
1218 @param aSpeedDialPosition The speed dial position. This is an integer in the |
|
1219 range 1 to 9 inclusive. If outside this range, the function leaves with |
|
1220 KErrArgument. |
|
1221 |
|
1222 @leave KErrDiskFull The disk does not have enough free space to perform the |
|
1223 operation. |
|
1224 |
|
1225 @capability ReadUserData |
|
1226 @capability WriteUserData |
|
1227 */ |
|
1228 void RCntModel::SetFieldAsSpeedDialL(TContactItemId aContactId, TInt aFieldIndex, TInt aSpeedDialPosition) |
|
1229 { |
|
1230 __ASSERT_ALWAYS(aSpeedDialPosition >= KCntMinSpeedDialIndex && aSpeedDialPosition <= KCntMaxSpeedDialIndex , User::Leave(KErrArgument)); |
|
1231 TIpcArgs args(aSpeedDialPosition, aContactId, aFieldIndex); |
|
1232 User::LeaveIfError(SendReceive(ECntSetSpeedDialIdForPosition, args)); |
|
1233 } |
|
1234 |
|
1235 |
|
1236 /** |
|
1237 Removes the mapping between a contact item field and a speed dial position. |
|
1238 |
|
1239 Removes the KUidSpeedDialXxx UID from the field's content type, removes the |
|
1240 field's speed dial attribute and commits the changes to the item. |
|
1241 |
|
1242 @param aContactId The ID of the contact item containing the speed dial field. |
|
1243 @param aSpeedDialPosition The speed dial position. This is an integer in the |
|
1244 range 1 to 9 inclusive. If outside this range, the function leaves with |
|
1245 KErrArgument. |
|
1246 |
|
1247 @leave KErrDiskFull The disk does not have enough free space to perform the operation. |
|
1248 |
|
1249 @capability ReadUserData |
|
1250 @capability WriteUserData |
|
1251 */ |
|
1252 void RCntModel::RemoveSpeedDialFieldL(TContactItemId aContactId, TInt aSpeedDialPosition) |
|
1253 { |
|
1254 __ASSERT_ALWAYS(aSpeedDialPosition >= KCntMinSpeedDialIndex && aSpeedDialPosition <= KCntMaxSpeedDialIndex , User::Leave(KErrArgument)); |
|
1255 // Tell the server that this speed dial slot is now free. Third argument |
|
1256 // (i.e. field index) is not used. |
|
1257 TIpcArgs args(aSpeedDialPosition, aContactId, -1); |
|
1258 User::LeaveIfError(SendReceive(ECntSetSpeedDialIdForPosition, args)); |
|
1259 } |
|
1260 |
|
1261 |
|
1262 /** |
|
1263 Returns the ID of the template that should be used with CContactICCEntry items. |
|
1264 If aPhonebookUid is set, the ID of the template belonging to the phonebook with |
|
1265 TUid aPhonebookUid is returned. |
|
1266 |
|
1267 @param aPhonebookUid The phonebook ID with default KNullUid. |
|
1268 |
|
1269 @return A template ID. |
|
1270 */ |
|
1271 TContactItemId RCntModel::ICCTemplateIdL(TUid aPhonebookUid) |
|
1272 { |
|
1273 TIpcArgs args(aPhonebookUid.iUid); |
|
1274 return SendReceive(ECntICCTemplateId, args); |
|
1275 } |
|
1276 |
|
1277 |
|
1278 /** |
|
1279 Returns the ID of the contacts model group which represents the ADN phonebook. |
|
1280 |
|
1281 @return ADN phonebook group ID. |
|
1282 */ |
|
1283 TContactItemId RCntModel::PhonebookGroupIdL() |
|
1284 { |
|
1285 return SendReceive(ECntPhonebookGroupId); |
|
1286 } |
|
1287 |
|
1288 |
|
1289 /** |
|
1290 Sets an existing contact item to be the database's current own card. |
|
1291 |
|
1292 @param aContact The contact item to set as the database's current own card. |
|
1293 It must already exist in the database. It cannot be a group or a template. |
|
1294 |
|
1295 @leave KErrNotFound aContact does not exist in the database. |
|
1296 @leave KErrDiskFull The disk does not have enough free space to perform the |
|
1297 operation. |
|
1298 |
|
1299 @capability None |
|
1300 */ |
|
1301 void RCntModel::SetOwnCardL(const CContactItem& aContact) |
|
1302 { |
|
1303 TIpcArgs args; |
|
1304 TPtr8 ptr(iPackager->PackL(aContact)); |
|
1305 args.Set(0,&ptr); |
|
1306 User::LeaveIfError(SendReceive(ECntSetOwnCard, args)); |
|
1307 } |
|
1308 |
|
1309 |
|
1310 /** |
|
1311 Returns the ID of the database's current own card. |
|
1312 |
|
1313 Having obtained this ID, the client may then open the own card in the same |
|
1314 way as an ordinary contact card (using ReadContactL() or OpenContactL()). |
|
1315 |
|
1316 @return The ID of the database's current own card. KNullContactId if the own |
|
1317 card has been deleted or has not yet been set. |
|
1318 */ |
|
1319 TContactItemId RCntModel::OwnCard() const |
|
1320 { |
|
1321 return static_cast<TContactItemId>(SendReceive(ECntGetOwnCard)); |
|
1322 } |
|
1323 |
|
1324 |
|
1325 /** |
|
1326 Returns the connection ID of the current client session. |
|
1327 |
|
1328 @return Connection ID of the current client session. |
|
1329 */ |
|
1330 TInt RCntModel::ConnectionId() const |
|
1331 { |
|
1332 // If asking for the connection ID the first time, then we ask the server |
|
1333 // about the session id (lazy initialisation). |
|
1334 if (!iConnectionId) |
|
1335 { |
|
1336 iConnectionId = SendReceive(ECntConnectionId); |
|
1337 } |
|
1338 return iConnectionId; |
|
1339 } |
|
1340 |
|
1341 |
|
1342 /** |
|
1343 Debug only. |
|
1344 |
|
1345 @capability None |
|
1346 */ |
|
1347 void RCntModel::SetHeapFailure(RHeap::TAllocFail aType, TInt aRate) |
|
1348 { |
|
1349 TIpcArgs args(aType,aRate); |
|
1350 SendReceive(ECntSetHeapFailure,args); |
|
1351 } |
|
1352 |
|
1353 |
|
1354 /** |
|
1355 Debug only. |
|
1356 |
|
1357 @return The heap size usage of the server in debug mode, 0 in release mode. |
|
1358 |
|
1359 @capability None |
|
1360 */ |
|
1361 TInt RCntModel::ResourceCount() |
|
1362 { |
|
1363 return(SendReceive(ECntResourceCount)); |
|
1364 } |
|
1365 |
|
1366 |
|
1367 /** |
|
1368 Returns the ID of the database's preferred template, as set by the method |
|
1369 SetPrefTemplateL(). The preferred template is for clients who may have |
|
1370 multiple templates but want to identify one as preferred. |
|
1371 |
|
1372 @return The ID of the database's current preferred template. KNullContactId if |
|
1373 not set. |
|
1374 */ |
|
1375 TContactItemId RCntModel::PrefTemplateId() const |
|
1376 { |
|
1377 return(SendReceive(ECntGetPrefTemplateId)); |
|
1378 } |
|
1379 |
|
1380 |
|
1381 /** |
|
1382 Sets the database's preferred template. |
|
1383 |
|
1384 The preferred template's ID persists when the database is opened and closed. |
|
1385 If the preferred template is subsequently deleted, the preferred template |
|
1386 ID is set to KNullContactId. |
|
1387 |
|
1388 @param aContact The contact card template to set as the database's preferred |
|
1389 template. |
|
1390 |
|
1391 @leave KErrNotSupported The item is not a template (i.e. is not of type |
|
1392 KUidContactCardTemplate). |
|
1393 @leave KErrDiskFull The disk does not have enough free space to perform the |
|
1394 operation. |
|
1395 |
|
1396 @capability WriteUserData |
|
1397 */ |
|
1398 void RCntModel::SetPrefTemplateL(const TContactItemId aContactId) |
|
1399 { |
|
1400 TIpcArgs args(aContactId); |
|
1401 User::LeaveIfError(SendReceive(ECntSetPrefTemplateId, args)); |
|
1402 } |
|
1403 |
|
1404 |
|
1405 /** |
|
1406 Get a list of template IDs from the server. |
|
1407 |
|
1408 @return Array of template IDs. |
|
1409 */ |
|
1410 CContactIdArray* RCntModel::FetchTemplateListIdsL() |
|
1411 { |
|
1412 TIpcArgs args; |
|
1413 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
1414 |
|
1415 TInt newBuffSize; |
|
1416 User::LeaveIfError(newBuffSize = SendReceive(ECntFetchTemplateIds, args)); |
|
1417 if (newBuffSize > 0) |
|
1418 { |
|
1419 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
1420 User::LeaveIfError(newBuffSize = SendReceive(ECntFetchTemplateIds, args)); |
|
1421 } |
|
1422 |
|
1423 CContactIdArray* idArray = iPackager->UnpackCntIdArrayLC(); |
|
1424 CleanupStack::Pop(idArray); |
|
1425 |
|
1426 return idArray; |
|
1427 } |
|
1428 |
|
1429 |
|
1430 /** |
|
1431 Get a list of group IDs from the server. |
|
1432 |
|
1433 @return Array of group IDs. |
|
1434 */ |
|
1435 CContactIdArray* RCntModel::FetchGroupListIdsL() |
|
1436 { |
|
1437 TIpcArgs args; |
|
1438 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
1439 |
|
1440 TInt newBuffSize; |
|
1441 User::LeaveIfError(newBuffSize = SendReceive(ECntFetchGroupIdLists, args)); |
|
1442 if (newBuffSize > 0) |
|
1443 { |
|
1444 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
1445 User::LeaveIfError(newBuffSize = SendReceive(ECntFetchGroupIdLists, args)); |
|
1446 } |
|
1447 |
|
1448 CContactIdArray* idArray = iPackager->UnpackCntIdArrayLC(); |
|
1449 CleanupStack::Pop(idArray); |
|
1450 |
|
1451 return idArray; |
|
1452 } |
|
1453 |
|
1454 |
|
1455 /** |
|
1456 Get a collection of contact IDs using the specified collection parameters. |
|
1457 |
|
1458 @param aCollectionType Type of collection. |
|
1459 @param aTime Used if collection type is "changed since". |
|
1460 @param aGuid Used if collection type is "find GUID". |
|
1461 |
|
1462 @return Contact ID array of those contacts which match the specified collection |
|
1463 parameters. |
|
1464 */ |
|
1465 CContactIdArray* RCntModel::CollectionL(TInt aCollectionType, TTime aTime,const TDesC& aGuid) |
|
1466 { |
|
1467 CContactIdArray* idArray = NULL; |
|
1468 switch(aCollectionType) |
|
1469 { |
|
1470 case MLplCollection::EChangedSince : |
|
1471 { |
|
1472 idArray = DoGetCollectionChangedSinceL(aTime); |
|
1473 } |
|
1474 break; |
|
1475 case MLplCollection::EDeleted : |
|
1476 case MLplCollection::EUnfiled : |
|
1477 { |
|
1478 idArray = DoGetCollectionL(aCollectionType); |
|
1479 } |
|
1480 break; |
|
1481 case MLplCollection::EFindGuid : |
|
1482 { |
|
1483 idArray = DoGetCollectionGuidL(aGuid); |
|
1484 } |
|
1485 break; |
|
1486 default: |
|
1487 { |
|
1488 User::Leave(KErrNotFound); |
|
1489 } |
|
1490 break; |
|
1491 } |
|
1492 return idArray; |
|
1493 } |
|
1494 |
|
1495 |
|
1496 /** |
|
1497 Get a collection of contact IDs which have changed since the given time. |
|
1498 |
|
1499 @param aTime Changed since time. |
|
1500 |
|
1501 @return Contact ID array of those contacts which have changed since the given |
|
1502 time. |
|
1503 */ |
|
1504 CContactIdArray* RCntModel::DoGetCollectionChangedSinceL(TTime aTime) |
|
1505 { |
|
1506 TIpcArgs args; |
|
1507 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
1508 args.Set(1,MLplCollection::EChangedSince); |
|
1509 TPckgBuf<TTime> pckg(aTime); |
|
1510 args.Set(2,&pckg); |
|
1511 |
|
1512 TInt newBuffSize; |
|
1513 User::LeaveIfError(newBuffSize = SendReceive(ECntGetCollection, args)); |
|
1514 if (newBuffSize > 0) |
|
1515 { |
|
1516 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
1517 User::LeaveIfError(newBuffSize = SendReceive(ECntGetCollection, args)); |
|
1518 } |
|
1519 |
|
1520 CContactIdArray* idArray = iPackager->UnpackCntIdArrayLC(); |
|
1521 CleanupStack::Pop(idArray); |
|
1522 |
|
1523 return idArray; |
|
1524 } |
|
1525 |
|
1526 |
|
1527 /** |
|
1528 Get a collection of contact IDs for the given collection type. |
|
1529 |
|
1530 @param aCollectionType Collection type. |
|
1531 |
|
1532 @return Contact ID array of those contacts which meet the given collection type |
|
1533 criteria. |
|
1534 */ |
|
1535 CContactIdArray* RCntModel::DoGetCollectionL(TInt aCollectionType) |
|
1536 { |
|
1537 TIpcArgs args; |
|
1538 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
1539 args.Set(1,aCollectionType); |
|
1540 |
|
1541 TInt newBuffSize; |
|
1542 User::LeaveIfError(newBuffSize = SendReceive(ECntGetCollection, args)); |
|
1543 if (newBuffSize > 0) |
|
1544 { |
|
1545 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
1546 User::LeaveIfError(newBuffSize = SendReceive(ECntGetCollection, args)); |
|
1547 } |
|
1548 |
|
1549 CContactIdArray* idArray = iPackager->UnpackCntIdArrayLC(); |
|
1550 CleanupStack::Pop(idArray); |
|
1551 |
|
1552 return idArray; |
|
1553 } |
|
1554 |
|
1555 |
|
1556 /** |
|
1557 Get a collection of contact IDs which have the given GUID. Since GUIDs are |
|
1558 unique (i.e. no two contacts can have the same GUID) there will only ever be |
|
1559 one contact ID in this collection. |
|
1560 |
|
1561 @param aGuid Contact GUID. |
|
1562 |
|
1563 @return Contact ID array containing the contact with the given GUID. |
|
1564 */ |
|
1565 CContactIdArray* RCntModel::DoGetCollectionGuidL(const TDesC& aGuid) |
|
1566 { |
|
1567 TIpcArgs args; |
|
1568 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
1569 args.Set(1,MLplCollection::EFindGuid); |
|
1570 args.Set(2,&aGuid); |
|
1571 |
|
1572 TInt newBuffSize; |
|
1573 User::LeaveIfError(newBuffSize = SendReceive(ECntGetCollection, args)); |
|
1574 if (newBuffSize > 0) |
|
1575 { |
|
1576 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
1577 User::LeaveIfError(newBuffSize = SendReceive(ECntGetCollection, args)); |
|
1578 } |
|
1579 |
|
1580 CContactIdArray* idArray = iPackager->UnpackCntIdArrayLC(); |
|
1581 CleanupStack::Pop(idArray); |
|
1582 |
|
1583 return idArray; |
|
1584 } |
|
1585 |
|
1586 |
|
1587 /** |
|
1588 Set the sort preferences in the server. |
|
1589 |
|
1590 @param aSortOrder Sort order preferences. |
|
1591 */ |
|
1592 void RCntModel::SetSortPreferenceL(const CArrayFix<CContactDatabase::TSortPref>& aSortOrder) |
|
1593 { |
|
1594 TPtr8 ptr(iPackager->PackL(aSortOrder)); |
|
1595 TIpcArgs args; |
|
1596 args.Set(0,&ptr); |
|
1597 User::LeaveIfError(SendReceive(ECntSetSortPrefs,args)); |
|
1598 } |
|
1599 |
|
1600 |
|
1601 /** |
|
1602 Get the sort preferences from the server. |
|
1603 |
|
1604 @return Sort order preferences. |
|
1605 */ |
|
1606 CArrayFix<CContactDatabase::TSortPref>* RCntModel::GetSortPreferenceL() const |
|
1607 { |
|
1608 TIpcArgs args; |
|
1609 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
1610 |
|
1611 TInt newBuffSize; |
|
1612 User::LeaveIfError(newBuffSize = SendReceive(ECntGetSortPrefs, args)); |
|
1613 if (newBuffSize > 0) |
|
1614 { |
|
1615 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
1616 User::LeaveIfError(newBuffSize = SendReceive(ECntGetSortPrefs, args)); |
|
1617 } |
|
1618 |
|
1619 CArrayFix<CContactDatabase::TSortPref>* prefs = iPackager->UnpackCArrayFixLC(); |
|
1620 CleanupStack::Pop(prefs); |
|
1621 |
|
1622 return prefs; |
|
1623 } |
|
1624 |
|
1625 |
|
1626 /** |
|
1627 Get the number of contacts in the database. |
|
1628 |
|
1629 @return Number of contacts in the database if successful, otherwise it leaves. |
|
1630 */ |
|
1631 TInt RCntModel::ContactCountL() const |
|
1632 { |
|
1633 TInt numContacts = SendReceive( ECntDbContactCount ); |
|
1634 User::LeaveIfError( numContacts ); |
|
1635 return numContacts; |
|
1636 } |
|
1637 |
|
1638 /** |
|
1639 Seek to the given contact ID. |
|
1640 |
|
1641 @param aContactId Contact ID to seek to. |
|
1642 @param aId On return the contact ID that the seek found. This will be the |
|
1643 nearest contact ID if the given aContactID cannot be found. |
|
1644 @param aContactType On return the contact type of the contact that the seek |
|
1645 found. |
|
1646 @param aDeleted On return ETrue if the contact that the seek found is marked as |
|
1647 deleted, EFalse otherwise. |
|
1648 |
|
1649 @return ETrue if the seek was successful, EFalse otherwise. |
|
1650 */ |
|
1651 TBool RCntModel::SeekContactL(TContactItemId aContactId,TContactItemId& aId,TUid& aContactType, TBool& aDeleted) |
|
1652 { |
|
1653 TPckgBuf<TInt> id; |
|
1654 TPckgBuf<TUid> type; |
|
1655 TPckgBuf<TBool> deleted; |
|
1656 TIpcArgs args(aContactId,&id,&type,&deleted); |
|
1657 TInt ret = SendReceive(ECntSeekContactInCollection,args); |
|
1658 |
|
1659 // Although ECntSeekContact/ECntSeekContactInCollection is normally completed |
|
1660 // with TBool values, ServiceError() can occur which leads to a negative system |
|
1661 // error codes being returned. User::LeaveIfError will allow that to be properly |
|
1662 // handled. |
|
1663 User::LeaveIfError(ret); |
|
1664 |
|
1665 if(ret) |
|
1666 { |
|
1667 aContactType = type(); |
|
1668 aId = id(); |
|
1669 aDeleted = deleted(); |
|
1670 return ETrue; |
|
1671 } |
|
1672 else |
|
1673 { |
|
1674 return EFalse; |
|
1675 } |
|
1676 } |
|
1677 |
|
1678 |
|
1679 void RCntModel::TextFieldL(TInt aCntItemId,TFieldType aFieldType, TDes& aText) |
|
1680 { |
|
1681 TPckgBuf<TFieldType> fieldType(aFieldType); |
|
1682 TIpcArgs args(aCntItemId,&fieldType,&aText); |
|
1683 User::LeaveIfError(SendReceive(ECntTextField,args)); |
|
1684 } |
|
1685 |
|
1686 |
|
1687 void RCntModel::ReadContactTextDefL(TContactItemId aContactId, TDes &aResult,const CContactTextDef& aTextDef) |
|
1688 { |
|
1689 iPackager->PackL( const_cast<CContactTextDef&>(aTextDef)); |
|
1690 TIpcArgs args(&iPackager->GetTransmittingBuffer(), &aResult,aContactId); |
|
1691 User::LeaveIfError(SendReceive(ECntReadContactTextDef, args)); |
|
1692 } |
|
1693 |
|
1694 |
|
1695 CContactIdArray* RCntModel::FindL(const TDesC& aText,const CContactItemFieldDef* aFieldDef) |
|
1696 { |
|
1697 TIpcArgs args; |
|
1698 |
|
1699 // Parameter can be NULL so send down an empty descriptor to the server. |
|
1700 // Server can detect this and pass NULL parameter to the Persistence Layer |
|
1701 // FindL() method. |
|
1702 if(aFieldDef != NULL) |
|
1703 { |
|
1704 // Packager's sending buffer in slot 1 (contains packed field |
|
1705 // definition). |
|
1706 iPackager->PackL(*aFieldDef); |
|
1707 args.Set(1,&iPackager->GetTransmittingBuffer()); |
|
1708 } |
|
1709 else |
|
1710 { |
|
1711 // Frigged NULL. |
|
1712 args.Set(1,&KNullDesC); |
|
1713 } |
|
1714 |
|
1715 // Packager's receiving buffer in slot 0. |
|
1716 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
1717 |
|
1718 // Text in slot 2. |
|
1719 args.Set(2,&aText); |
|
1720 |
|
1721 // Ensure receiving buffer is big enough. |
|
1722 TInt newBuffSize; |
|
1723 User::LeaveIfError(newBuffSize = SendReceive(ECntFind, args)); |
|
1724 if (newBuffSize > 0) |
|
1725 { |
|
1726 // Not big enough so resize and call again. |
|
1727 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
1728 User::LeaveIfError(newBuffSize = SendReceive(ECntFind, args)); |
|
1729 } |
|
1730 |
|
1731 CContactIdArray* idArray = iPackager->UnpackCntIdArrayLC(); |
|
1732 CleanupStack::Pop(idArray); |
|
1733 |
|
1734 return idArray; |
|
1735 } |
|
1736 |
|
1737 |
|
1738 void RCntModel::SetDbViewContactType(const TUid aUid) |
|
1739 { |
|
1740 TIpcArgs args(aUid.iUid); |
|
1741 (void)SendReceive(ECntSetDbViewContactType,args); |
|
1742 } |
|
1743 |
|
1744 |
|
1745 TUid RCntModel::GetDbViewContactType() const |
|
1746 { |
|
1747 TPckgBuf<TUid> type; |
|
1748 TIpcArgs args(&type); |
|
1749 (void)SendReceive(ECntSetDbViewContactType,args); |
|
1750 return type(); |
|
1751 } |
|
1752 |
|
1753 |
|
1754 /** |
|
1755 Initialise the Persistence Layer collection class ready for iterative calls to |
|
1756 the FindAsyncL() method. This form of initialisation is for an asynchronous |
|
1757 find which uses a text definition and an array of "find words". |
|
1758 |
|
1759 @param aWords "Find words" array. |
|
1760 @param aTextDef Text definition to use in find. |
|
1761 */ |
|
1762 void RCntModel::FindAsyncTextDefInitL(const CDesCArray& aWords,CContactTextDef* aTextDef) |
|
1763 { |
|
1764 TIpcArgs args; |
|
1765 if(aTextDef != NULL) |
|
1766 { |
|
1767 // Pack the text definition. |
|
1768 iPackager->PackL(*aTextDef); |
|
1769 args.Set(1,&iPackager->GetTransmittingBuffer()); |
|
1770 } |
|
1771 else |
|
1772 { |
|
1773 // No user supplied text definition. |
|
1774 args.Set(1, &KNullDesC); |
|
1775 } |
|
1776 |
|
1777 // Do the CDesCArray manually as Packager can't do both. |
|
1778 RBufWriteStream writeStream; |
|
1779 CBufFlat* buf = CBufFlat::NewL(1 << 8); |
|
1780 CleanupStack::PushL(buf); |
|
1781 |
|
1782 writeStream.Open(*buf); |
|
1783 TInt count = aWords.Count(); |
|
1784 writeStream.WriteInt32L(count); |
|
1785 TInt length = 0; |
|
1786 for(TInt i=0; i<count;++i) |
|
1787 { |
|
1788 length = aWords[i].Length(); |
|
1789 writeStream.WriteInt32L(length); |
|
1790 writeStream.WriteL(aWords[i],length); |
|
1791 } |
|
1792 writeStream.CommitL(); |
|
1793 writeStream.Close(); |
|
1794 |
|
1795 TPtr8 ptr8(buf->Ptr(0)); |
|
1796 args.Set(0,&ptr8); |
|
1797 |
|
1798 User::LeaveIfError(SendReceive(ECntFindAsyncTextDefInit,args)); |
|
1799 |
|
1800 CleanupStack::PopAndDestroy(buf); |
|
1801 } |
|
1802 |
|
1803 |
|
1804 /** |
|
1805 Initialise the Persistence Layer collection class ready for iterative calls to |
|
1806 the FindAsyncL() method. This form of initialisation is for an asynchronous |
|
1807 find which uses text and a field definition. |
|
1808 |
|
1809 @param aText Find text. |
|
1810 @param aFieldDef Field definition to use in find. |
|
1811 */ |
|
1812 void RCntModel::FindAsyncInitL(const TDesC& aText,CContactItemFieldDef* aFieldDef) |
|
1813 { |
|
1814 TIpcArgs args; |
|
1815 args.Set(0,&aText); |
|
1816 if(aFieldDef != NULL) |
|
1817 { |
|
1818 // Pack the field definition. |
|
1819 iPackager->PackL(*aFieldDef); |
|
1820 args.Set(1,&iPackager->GetTransmittingBuffer()); |
|
1821 } |
|
1822 else |
|
1823 { |
|
1824 // No user supplied field definition. |
|
1825 args.Set(1, &KNullDesC); |
|
1826 } |
|
1827 |
|
1828 User::LeaveIfError(SendReceive(ECntFindAsyncInit,args)); |
|
1829 } |
|
1830 |
|
1831 |
|
1832 /** |
|
1833 Perform an asynchronous find iteration. Either the FindAsyncTextDefInitL() or |
|
1834 the FindAsyncInitL() method above must have first been called. |
|
1835 |
|
1836 @param aOrigIdArray Set of contacts IDs from previous calls to FindAsyncL(). |
|
1837 Will be NULL if this is the first iteration. |
|
1838 |
|
1839 @return ETrue if further find iterations are required, EFalse otherwise. |
|
1840 */ |
|
1841 TBool RCntModel::FindAsyncL(CContactIdArray*& aOrigIdArray) |
|
1842 { |
|
1843 TBool moreToGo; |
|
1844 TPckg<TBool> pckg(moreToGo); |
|
1845 // Iterations can't fail so expand buffer to 4Kb. 4096 contacts should be |
|
1846 // enough. Rather than this brutal approach we could call ContactCountL() |
|
1847 // and add a contingency in case another client adds some. |
|
1848 TIpcArgs args(&iPackager->GetReceivingBufferL(4096),&pckg); |
|
1849 |
|
1850 User::LeaveIfError(SendReceive(ECntFindAsync,args)); |
|
1851 |
|
1852 CContactIdArray* newIdArray = iPackager->UnpackCntIdArrayLC(); |
|
1853 if(aOrigIdArray != NULL) |
|
1854 { |
|
1855 // Append to the old array if it was not NULL. |
|
1856 for(TInt i=0;i<newIdArray->Count();++i) |
|
1857 { |
|
1858 if(aOrigIdArray->Find((*newIdArray)[i]) == KErrNotFound) |
|
1859 { |
|
1860 //Add only when we are sure that this ID has not been added to this array before. |
|
1861 aOrigIdArray->AddL((*newIdArray)[i]); |
|
1862 } |
|
1863 } |
|
1864 CleanupStack::PopAndDestroy(newIdArray); |
|
1865 } |
|
1866 else |
|
1867 { |
|
1868 CleanupStack::Pop(newIdArray); |
|
1869 aOrigIdArray = newIdArray; |
|
1870 } |
|
1871 |
|
1872 return pckg(); |
|
1873 } |
|
1874 |
|
1875 |
|
1876 /** |
|
1877 Set the asynchronous activity flag in the server. Any asynchronous activity |
|
1878 such as asynchronous find or asynchronous sort prevent the database from |
|
1879 being closed and should set this flag. When all asynchronous activites are |
|
1880 finished this flag should be cleared. |
|
1881 |
|
1882 @capability None |
|
1883 |
|
1884 @param aAsyncActivity ETrue if at least one asynchronous activity, EFalse if |
|
1885 no asynchronous activities. |
|
1886 */ |
|
1887 void RCntModel::SetAsyncActivityL(TBool aAsyncActivity) |
|
1888 { |
|
1889 TIpcArgs args; |
|
1890 args.Set(0,aAsyncActivity); |
|
1891 User::LeaveIfError(SendReceive(ECntSetAsyncActivity,args)); |
|
1892 } |
|
1893 |
|
1894 |
|
1895 /** |
|
1896 Filter the database using the given filter. |
|
1897 |
|
1898 @param aFilter Filter to use. On return the contact IDs in this filter will be |
|
1899 augmented with those contact IDs which match the given filter. |
|
1900 */ |
|
1901 void RCntModel::FilterDatabaseL(CCntFilter& aFilter) |
|
1902 { |
|
1903 CContactIdArray* origIdArray = aFilter.iIds; |
|
1904 aFilter.iIds = NULL; |
|
1905 |
|
1906 TIpcArgs args; |
|
1907 iPackager->PackL(aFilter); |
|
1908 args.Set(1,&iPackager->GetTransmittingBuffer()); |
|
1909 args.Set(0, &iPackager->GetReceivingBufferL()); |
|
1910 |
|
1911 TInt newBuffSize(0); |
|
1912 User::LeaveIfError(newBuffSize = SendReceive(ECntFilterDatabase, args)); |
|
1913 if (newBuffSize > 0) |
|
1914 { |
|
1915 // Not big enough so resize and call again. |
|
1916 args.Set(0, &iPackager->GetReceivingBufferL(newBuffSize)); |
|
1917 User::LeaveIfError(newBuffSize = SendReceive(ECntFilterDatabase, args)); |
|
1918 } |
|
1919 |
|
1920 CContactIdArray* newIdArray = iPackager->UnpackCntIdArrayLC(); |
|
1921 if(origIdArray != NULL) |
|
1922 { |
|
1923 for(TInt i=0;i<newIdArray->Count();++i) |
|
1924 { |
|
1925 origIdArray->AddL((*newIdArray)[i]); |
|
1926 } |
|
1927 aFilter.iIds = origIdArray; |
|
1928 CleanupStack::PopAndDestroy(newIdArray); |
|
1929 } |
|
1930 else |
|
1931 { |
|
1932 CleanupStack::Pop(newIdArray); |
|
1933 aFilter.iIds = newIdArray; |
|
1934 } |
|
1935 } |
|
1936 |
|
1937 |
|
1938 TInt RCntModel::OpenViewL(const CContactTextDef& aTextDef, const TInt aViewPrefs) |
|
1939 { |
|
1940 TPckgBuf<TInt> viewSessionId; |
|
1941 iPackager->PackL(const_cast<CContactTextDef&>(aTextDef)); |
|
1942 TIpcArgs args(&iPackager->GetTransmittingBuffer(), aViewPrefs, &viewSessionId); |
|
1943 |
|
1944 TInt ret = SendReceive(ECntOpenViewSession,args); |
|
1945 User::LeaveIfError(ret); |
|
1946 |
|
1947 return viewSessionId(); |
|
1948 } |
|
1949 |
|
1950 |
|
1951 void RCntModel::CloseView(TInt aViewId) |
|
1952 { |
|
1953 TIpcArgs args(aViewId); |
|
1954 SendReceive(ECntCloseViewSession,args); |
|
1955 } |
|
1956 |
|
1957 |
|
1958 void RCntModel::ChangeSortOrderL(TInt aViewId, const CContactTextDef& aTextDef) |
|
1959 { |
|
1960 // Serialize the text def using packager overload. |
|
1961 iPackager->PackL( const_cast<CContactTextDef&>(aTextDef)); |
|
1962 |
|
1963 |
|
1964 TIpcArgs args(aViewId, &iPackager->GetTransmittingBuffer()); |
|
1965 TInt ret = SendReceive(ECntViewChangeSortOrderL, args); |
|
1966 |
|
1967 User::LeaveIfError(ret); |
|
1968 } |
|
1969 |
|
1970 |
|
1971 void RCntModel::BeginIterateL(TInt aViewId) |
|
1972 { |
|
1973 TIpcArgs args(aViewId); |
|
1974 TInt ret = SendReceive(ECntViewBeginIterate,args); |
|
1975 User::LeaveIfError(ret); |
|
1976 } |
|
1977 |
|
1978 |
|
1979 void RCntModel::EndIterateL(TInt aViewId) |
|
1980 { |
|
1981 TIpcArgs args(aViewId); |
|
1982 TInt ret = SendReceive(ECntViewEndIterate,args); |
|
1983 User::LeaveIfError(ret); |
|
1984 } |
|
1985 |
|
1986 |
|
1987 CViewContact* RCntModel::NextItemL(TInt aViewId, const TInt aViewPrefs) |
|
1988 { |
|
1989 TIpcArgs args(aViewId, aViewPrefs, &iPackager->GetReceivingBufferL()); |
|
1990 TInt size = SendReceive(ECntViewNextItemL, args); |
|
1991 |
|
1992 // KErrNotFound is returned if Persistence Layer view item manager |
|
1993 // can't reach end of the contacts. |
|
1994 if(size == KErrNotFound) |
|
1995 { |
|
1996 // Not an error just no match. |
|
1997 return NULL; |
|
1998 } |
|
1999 |
|
2000 // Leave on genuine errors. |
|
2001 User::LeaveIfError(size); |
|
2002 |
|
2003 if(size != 0) // Server session requires larger packager buffer. |
|
2004 { |
|
2005 // Increase the buffer size and call again. Just in case some other |
|
2006 // client has deleted in between calls do the KErrNotFound check. |
|
2007 TIpcArgs args(aViewId, aViewPrefs, &iPackager->GetReceivingBufferL(size)); |
|
2008 TInt ret = SendReceive(ECntViewNextItemL, args); |
|
2009 if(ret == KErrNotFound) |
|
2010 { |
|
2011 return NULL; |
|
2012 } |
|
2013 // Leave on genuine errors |
|
2014 User::LeaveIfError(ret); |
|
2015 } |
|
2016 |
|
2017 // Got it so unpack and return. |
|
2018 CViewContact* viewContact = iPackager->UnpackViewContactLC(); |
|
2019 |
|
2020 CleanupStack::Pop(viewContact); |
|
2021 |
|
2022 return viewContact; |
|
2023 } |
|
2024 |
|
2025 |
|
2026 CViewContact* RCntModel::ItemAtL(TContactItemId aContactId, TInt aViewId) |
|
2027 { |
|
2028 TIpcArgs args(aContactId, aViewId, &iPackager->GetReceivingBufferL()); |
|
2029 TInt size = SendReceive(ECntItemAtL, args); |
|
2030 |
|
2031 // KErrNotFound is returned if Persistence Layer view item manager cannot |
|
2032 // find the view contact by given aContactId. |
|
2033 if(size == KErrNotFound) |
|
2034 { |
|
2035 // Not an error just no match. |
|
2036 return NULL; |
|
2037 } |
|
2038 |
|
2039 // Leave on genuine errors. |
|
2040 User::LeaveIfError(size); |
|
2041 |
|
2042 if(size != 0) // Server session requires larger packager buffer. |
|
2043 { |
|
2044 // Increase the buffer size and call again. Just in case some other |
|
2045 // client has deleted in between calls do the KErrNotFound check. |
|
2046 TIpcArgs args(aContactId, aViewId, &iPackager->GetReceivingBufferL(size)); |
|
2047 TInt ret = SendReceive(ECntItemAtL, args); |
|
2048 if(ret == KErrNotFound) |
|
2049 { |
|
2050 return NULL; |
|
2051 } |
|
2052 // Leave on genuine errors |
|
2053 User::LeaveIfError(ret); |
|
2054 } |
|
2055 |
|
2056 // Got it so unpack and return. |
|
2057 CViewContact* viewContact = iPackager->UnpackViewContactLC(); |
|
2058 |
|
2059 CleanupStack::Pop(viewContact); |
|
2060 |
|
2061 return viewContact; |
|
2062 } |
|
2063 |
|
2064 |
|
2065 #if defined(_DEBUG) |
|
2066 void RCntModel::GetDefinitionsOfExistingViewsL(const TDesC& aDbName, RPointerArray<CContactDefaultViewDefinition>& aViewDefs) |
|
2067 { |
|
2068 RBuf8 buf; |
|
2069 CleanupClosePushL(buf); |
|
2070 buf.Create(256); |
|
2071 TIpcArgs args(&aDbName, &buf); |
|
2072 |
|
2073 TInt newBufSize; |
|
2074 User::LeaveIfError(newBufSize = SendReceive(ECntGetDefinitionsForExistingView, args)); |
|
2075 if (newBufSize > 0) |
|
2076 { |
|
2077 buf.ReAllocL(newBufSize); |
|
2078 args.Set(1, &buf); |
|
2079 User::LeaveIfError(newBufSize = SendReceive(ECntGetDefinitionsForExistingView, args)); |
|
2080 } |
|
2081 |
|
2082 RDesReadStream readStream(buf); |
|
2083 CleanupClosePushL(readStream); |
|
2084 TInt32 count; |
|
2085 readStream >> count; |
|
2086 CContactDefaultViewDefinition* view; |
|
2087 for (TInt i = 0; i < count; i++) |
|
2088 { |
|
2089 view = CContactDefaultViewDefinition::NewLC(readStream); |
|
2090 aViewDefs.AppendL(view); |
|
2091 CleanupStack::Pop(view); |
|
2092 } |
|
2093 |
|
2094 CleanupStack::PopAndDestroy(2); // readStream, buf |
|
2095 } |
|
2096 #else |
|
2097 void RCntModel::GetDefinitionsOfExistingViewsL(const TDesC& /*aDbName*/, RPointerArray<CContactDefaultViewDefinition>& /*aViewDefs*/) |
|
2098 { |
|
2099 } |
|
2100 #endif // _DEBUG |