|
1 /* |
|
2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Predefined contacts engine (state machine) |
|
15 * |
|
16 */ |
|
17 |
|
18 // System includes |
|
19 #include <CVPbkContactManager.h> // CVPbkContactManager |
|
20 #include <MVPbkContactStoreList.h> // MVPbkContactStoreList |
|
21 #include <MVPbkContactStore.h> // MVPbkContactStore |
|
22 #include <CVPbkContactStoreUriArray.h> // CVPbkContactStoreUriArray |
|
23 #include <TVPbkContactStoreUriPtr.h> // TVPbkContactStoreUriPtr |
|
24 #include <CVPbkContactLinkArray.h> // CVPbkContactLinkArray |
|
25 #include <VPbkContactStoreUris.h> // VPbkContactStoreUris |
|
26 #include <AknGlobalNote.h> // CAknGlobalNote |
|
27 #include <stringresourcereader.h> // CStringResourceReader |
|
28 #include <predefinedcontacts.rsg> |
|
29 |
|
30 // User includes |
|
31 #include "PdcEngine.h" // CPdcEngine |
|
32 #include "PdcVCardImporter.h" // CPdcVCardImporter |
|
33 #include "PdcXMLImporter.h" // CPdcXmlImporter |
|
34 #include "pdcdata.h" // CPdcData |
|
35 #include "pdccontactdeletion.h" // CPdcContactDeletion |
|
36 #include "pdclogger.h" |
|
37 |
|
38 // Constants |
|
39 _LIT( KErrorResourceFile, "z:\\resource\\predefinedcontacts.rsc" ); |
|
40 |
|
41 #ifdef USE_FILE_LOGGER |
|
42 _LIT(KLogsPath,"c:\\logs\\predefinedcontacts\\"); |
|
43 #endif |
|
44 |
|
45 // ======== MEMBER FUNCTIONS ======== |
|
46 |
|
47 // --------------------------------------------------------------------------- |
|
48 // CPdcEngine::NewLC |
|
49 // Symbian 1st phase constructor |
|
50 // @return Self pointer to CPdcEngine pushed to |
|
51 // the cleanup stack. |
|
52 // --------------------------------------------------------------------------- |
|
53 // |
|
54 CPdcEngine* CPdcEngine::NewLC() |
|
55 { |
|
56 CPdcEngine* self = new( ELeave ) CPdcEngine(); |
|
57 CleanupStack::PushL(self); |
|
58 self->ConstructL(); |
|
59 return self; |
|
60 } |
|
61 |
|
62 // --------------------------------------------------------------------------- |
|
63 // CPdcEngine::~CPdcEngine |
|
64 // Destructor |
|
65 // --------------------------------------------------------------------------- |
|
66 // |
|
67 CPdcEngine::~CPdcEngine() |
|
68 { |
|
69 Cancel(); |
|
70 delete iLinkArray; |
|
71 delete iVCardImporter; |
|
72 delete iXmlImporter; |
|
73 delete iFileDirectory; |
|
74 delete iPdcData; |
|
75 delete iContactDeleter; |
|
76 |
|
77 if (iContactStore) |
|
78 { |
|
79 iContactStore->Close( *this); |
|
80 } |
|
81 |
|
82 delete iContactManager; |
|
83 |
|
84 iFs.Close(); |
|
85 } |
|
86 |
|
87 // --------------------------------------------------------------------------- |
|
88 // CPdcEngine::CPdcEngine |
|
89 // C++ constructor |
|
90 // --------------------------------------------------------------------------- |
|
91 // |
|
92 CPdcEngine::CPdcEngine() : |
|
93 CActive(EPriorityNormal) |
|
94 { |
|
95 } |
|
96 |
|
97 // --------------------------------------------------------------------------- |
|
98 // CPdcEngine::ConstructL |
|
99 // Second-phase constructor |
|
100 // --------------------------------------------------------------------------- |
|
101 // |
|
102 void CPdcEngine::ConstructL() |
|
103 { |
|
104 // Connect to the file system |
|
105 User::LeaveIfError(iFs.Connect() ); |
|
106 |
|
107 #ifdef USE_FILE_LOGGER |
|
108 iFs.MkDirAll(KLogsPath); // create file logger path |
|
109 #endif |
|
110 LOGTEXT( _L("CPdcEngine::ConstructL") ); |
|
111 |
|
112 // Create the array of links |
|
113 iLinkArray = CVPbkContactLinkArray::NewL(); |
|
114 // Create data checker |
|
115 iPdcData = CPdcData::NewL(iFs, *iLinkArray); |
|
116 |
|
117 // Add to the activeScheduler |
|
118 CActiveScheduler::Add( this); |
|
119 } |
|
120 |
|
121 // --------------------------------------------------------------------------- |
|
122 // CPdcEngine::PredefinedContactsNeedAddingL |
|
123 // Checks if the predefined contacts need to be added. |
|
124 // @return ETrue if the predefined contacts need to be added |
|
125 // --------------------------------------------------------------------------- |
|
126 // |
|
127 TBool CPdcEngine::PredefinedContactsNeedAddingL() |
|
128 { |
|
129 LOGTEXT( _L("CPdcEngine::PredefinedContactsNeedAddingL") ); |
|
130 return iPdcData->ContactsUpToDateL(); |
|
131 } |
|
132 |
|
133 // --------------------------------------------------------------------------- |
|
134 // CPdcEngine::AddPredefinedContactsL |
|
135 // Starts the asyncronous process of reading and adding the |
|
136 // predefined contacts to the contact model |
|
137 // --------------------------------------------------------------------------- |
|
138 // |
|
139 void CPdcEngine::AddPredefinedContactsL() |
|
140 { |
|
141 LOGTEXT( _L("CPdcEngine::AddPredefinedContactsL") ); |
|
142 // Begin the process of adding of the prefined contacts creating the |
|
143 // contact manager |
|
144 CVPbkContactStoreUriArray* uriArray = CVPbkContactStoreUriArray::NewLC(); |
|
145 |
|
146 // get the default Contacts Model database store URI. |
|
147 const TDesC& cntDbUri = VPbkContactStoreUris::DefaultCntDbUri(); |
|
148 uriArray->AppendL(cntDbUri); |
|
149 |
|
150 // Create the contact manager |
|
151 iContactManager = CVPbkContactManager::NewL( *uriArray); |
|
152 CleanupStack::PopAndDestroy(uriArray); |
|
153 |
|
154 // Get the store list |
|
155 MVPbkContactStoreList& storeList = iContactManager->ContactStoresL(); |
|
156 |
|
157 // Get the store |
|
158 iContactStore = storeList.Find(cntDbUri); |
|
159 ASSERT( iContactStore ); |
|
160 |
|
161 // Open the store |
|
162 iContactStore->OpenL( *this); |
|
163 |
|
164 // Set the engine state to opening the contacts database, and await the |
|
165 // the store ready callback. |
|
166 iEngineState = EOpeningContacts; |
|
167 } |
|
168 |
|
169 // --------------------------------------------------------------------------- |
|
170 // CPdcEngine::AddPredefinedContactsL |
|
171 // Starts the asyncronous process of reading and adding the |
|
172 // predefined contacts to the contact model |
|
173 // @param aStatus TRequestStatus of caller (called by ECom |
|
174 // plugin starting mechanism. |
|
175 // --------------------------------------------------------------------------- |
|
176 // |
|
177 void CPdcEngine::AddPredefinedContactsL(TRequestStatus& aCallerStatus) |
|
178 { |
|
179 iCallerStatus = &aCallerStatus; |
|
180 aCallerStatus = KRequestPending; |
|
181 |
|
182 AddPredefinedContactsL(); |
|
183 } |
|
184 |
|
185 // --------------------------------------------------------------------------- |
|
186 // CPdcEngine::SelfComplete |
|
187 // Signals that the AO should be run again by completing the outstanding |
|
188 // TRequestStatus. |
|
189 // --------------------------------------------------------------------------- |
|
190 // |
|
191 void CPdcEngine::SelfComplete() |
|
192 { |
|
193 // Begin the process of adding of the prefined contacts to contacts |
|
194 TRequestStatus* status = &iStatus; |
|
195 User::RequestComplete(status, KErrNone); |
|
196 SetActive(); |
|
197 } |
|
198 |
|
199 // --------------------------------------------------------------------------- |
|
200 // CPdcEngine::DoCancel |
|
201 // From CActive |
|
202 // Cancels any outstanding async operations. |
|
203 // --------------------------------------------------------------------------- |
|
204 // |
|
205 void CPdcEngine::DoCancel() |
|
206 { |
|
207 LOGTEXT( _L("CPdcEngine::Cancel") ); |
|
208 |
|
209 if( iVCardImporter ) |
|
210 { |
|
211 iVCardImporter->Cancel(); |
|
212 } |
|
213 if( iXmlImporter ) |
|
214 { |
|
215 iXmlImporter->Cancel(); |
|
216 } |
|
217 if( iContactDeleter ) |
|
218 { |
|
219 iContactDeleter->Cancel(); |
|
220 } |
|
221 if( iCallerStatus ) |
|
222 { |
|
223 User::RequestComplete( iCallerStatus, KErrCancel); |
|
224 } |
|
225 } |
|
226 |
|
227 // --------------------------------------------------------------------------- |
|
228 // CPdcEngine::RunL |
|
229 // From CActive |
|
230 // Handles the objects request completion event by performing the relevent |
|
231 // action for the current state. |
|
232 // --------------------------------------------------------------------------- |
|
233 // |
|
234 void CPdcEngine::RunL() |
|
235 { |
|
236 |
|
237 //Reserve error info before going into next step |
|
238 if (iStatus!= KErrNone) |
|
239 { |
|
240 LOGTEXT2(_L("error happend iStatus = %d"), iStatus.Int() ); |
|
241 User::LeaveIfError(iStatus.Int() ); |
|
242 } |
|
243 |
|
244 switch (iEngineState) |
|
245 { |
|
246 case EDeleteOldContacts: |
|
247 { |
|
248 LOGTEXT(_L("EDeleteOldContacts")); |
|
249 DeleteContactsL(); |
|
250 |
|
251 // Set the next state |
|
252 iEngineState = EGettingFileLocation; |
|
253 } |
|
254 break; |
|
255 case EGettingFileLocation: |
|
256 { |
|
257 // Reset the link array |
|
258 LOGTEXT(_L("EGettingFileLocation")); |
|
259 GetFileLocationL(); |
|
260 |
|
261 // Set the next state |
|
262 iEngineState = EReadingVCards; |
|
263 } |
|
264 break; |
|
265 case EReadingVCards: |
|
266 { |
|
267 LOGTEXT(_L("EReadingVCards")); |
|
268 ReadVCardsL(); |
|
269 |
|
270 // Set the next state |
|
271 iEngineState = EReadingXML; |
|
272 } |
|
273 break; |
|
274 case EReadingXML: |
|
275 { |
|
276 LOGTEXT(_L("EReadingXML")); |
|
277 ReadXmlL(); |
|
278 |
|
279 // Set the next state |
|
280 iEngineState = EUpdateData; |
|
281 } |
|
282 break; |
|
283 case EUpdateData: |
|
284 { |
|
285 LOGTEXT(_L("EUpdateData")); |
|
286 TRAPD( error, UpdateDataL() ) |
|
287 ; |
|
288 if (error) |
|
289 { |
|
290 TRAP_IGNORE( DisplayErrorNoteL( error, iEngineState, EFalse ) ); |
|
291 } |
|
292 |
|
293 // Set the next state |
|
294 iEngineState = EFinish; |
|
295 } |
|
296 break; |
|
297 case EDeleteStoredContact: |
|
298 { |
|
299 LOGTEXT(_L("EDeleteStoredContact")); |
|
300 iDeletedStoredContact = EFalse; |
|
301 DeleteStoredContactsL(); |
|
302 |
|
303 // Set the next state |
|
304 iEngineState = EFinish; |
|
305 } |
|
306 break; |
|
307 case EFinish: |
|
308 { |
|
309 LOGTEXT(_L("EFinish")); |
|
310 Finish(KErrNone); |
|
311 } |
|
312 break; |
|
313 default: |
|
314 { |
|
315 // Should never reach this point |
|
316 ASSERT( 0 ); |
|
317 } |
|
318 break; |
|
319 } |
|
320 } |
|
321 |
|
322 // --------------------------------------------------------------------------- |
|
323 // CPdcEngine::RunError |
|
324 // From CActive |
|
325 // Called when RunL leaves. |
|
326 // --------------------------------------------------------------------------- |
|
327 // |
|
328 TInt CPdcEngine::RunError(TInt aError) |
|
329 { |
|
330 LOGTEXT(_L("RunError")); |
|
331 //flag for represent XML or vCard error |
|
332 TBool needDelete = EFalse; |
|
333 |
|
334 //Display the error message. |
|
335 TInt iErrPosition = iEngineState - 1; |
|
336 |
|
337 TRAP_IGNORE( DisplayErrorNoteL( aError, iErrPosition, EFalse ) ) |
|
338 |
|
339 if (EReadingVCards == iErrPosition || EReadingXML == iErrPosition) |
|
340 { |
|
341 needDelete = ETrue; |
|
342 } |
|
343 |
|
344 //XML or vCard error, so return to RunL and delete the stored contacts. |
|
345 if (needDelete) |
|
346 { |
|
347 iEngineState = EDeleteStoredContact; |
|
348 SelfComplete(); |
|
349 } |
|
350 else |
|
351 { |
|
352 // Stop the code executing. |
|
353 Finish(aError); |
|
354 } |
|
355 |
|
356 // Don't propagate the error to the active scheduler, (otherwise the |
|
357 // active scheduler by default will panic). |
|
358 return KErrNone; |
|
359 } |
|
360 |
|
361 // --------------------------------------------------------------------------- |
|
362 // CPdcEngine::DeleteOldContactsL |
|
363 // Checks to see if there are any exisitng contacts that need to be |
|
364 // deleted, if so starts the asycnronous deletion of the contacts. |
|
365 // --------------------------------------------------------------------------- |
|
366 // |
|
367 void CPdcEngine::DeleteContactsL() |
|
368 { |
|
369 // Get old contacts |
|
370 HBufC8* linkBuffer = iPdcData->LinkArrayBuffer(); |
|
371 if (linkBuffer) |
|
372 { |
|
373 // Create the contacts deletion object |
|
374 iContactDeleter = CPdcContactDeletion::NewL( *iContactManager); |
|
375 iDeletedStoredContact = ETrue; |
|
376 // Get the links array |
|
377 MVPbkContactLinkArray* linkArray = |
|
378 iContactManager->CreateLinksLC( *linkBuffer); |
|
379 |
|
380 // Start deleting the contacts, takes ownership of the link |
|
381 // array. |
|
382 iContactDeleter->DeleteContactsL(linkArray, iStatus, |
|
383 iDeletedStoredContact); |
|
384 CleanupStack::Pop(); // linkArray |
|
385 |
|
386 SetActive(); |
|
387 } |
|
388 else |
|
389 { |
|
390 // Queue a request for the next state |
|
391 SelfComplete(); |
|
392 } |
|
393 } |
|
394 |
|
395 // --------------------------------------------------------------------------- |
|
396 // CPdcEngine::GetFileLocationL |
|
397 // Gets the file location of any vCards and xml scripts |
|
398 // --------------------------------------------------------------------------- |
|
399 // |
|
400 void CPdcEngine::GetFileLocationL() |
|
401 { |
|
402 // Get the location of the predefined contacts vCards and/or XML |
|
403 // script |
|
404 iFileDirectory = iPdcData->GetFileLocationL(); |
|
405 |
|
406 // Queue a request for the next state |
|
407 SelfComplete(); |
|
408 } |
|
409 |
|
410 // --------------------------------------------------------------------------- |
|
411 // CPdcEngine::ReadVCardsL |
|
412 // Starts the asyncrous importation of contacts from vCards |
|
413 // --------------------------------------------------------------------------- |
|
414 // |
|
415 void CPdcEngine::ReadVCardsL() |
|
416 { |
|
417 // Create the vCard importer |
|
418 iVCardImporter = CPdcVCardImporter::NewL(iFs, *iContactManager, |
|
419 *iContactStore, *iLinkArray); |
|
420 // Read in any vCards asyncronously |
|
421 iVCardImporter->GetVCardsL( *iFileDirectory, iStatus); |
|
422 SetActive(); |
|
423 } |
|
424 |
|
425 // --------------------------------------------------------------------------- |
|
426 // CPdcEngine::ReadXmlL |
|
427 // Starts the asycnronous importation of contacts from the XML script |
|
428 // --------------------------------------------------------------------------- |
|
429 // |
|
430 void CPdcEngine::ReadXmlL() |
|
431 { |
|
432 // Create the XML importer |
|
433 iXmlImporter = CPdcXmlImporter::NewL(iFs, *iContactStore, *iLinkArray); |
|
434 |
|
435 //transfer the pointer of ContactManager to Xmlimporter |
|
436 iXmlImporter->SetContactManager(iContactManager); |
|
437 // Read any contacts from XML asyncronously |
|
438 iXmlImporter->GetXmlContactsL( *iFileDirectory, iStatus); |
|
439 |
|
440 SetActive(); |
|
441 } |
|
442 |
|
443 // --------------------------------------------------------------------------- |
|
444 // CPdcEngine::UpdateDataL |
|
445 // Persists the internal data to file ( including links to any contacts |
|
446 // that have been added ) |
|
447 // --------------------------------------------------------------------------- |
|
448 // |
|
449 void CPdcEngine::UpdateDataL() |
|
450 { |
|
451 // Update the data |
|
452 iPdcData->StoreL(); |
|
453 |
|
454 // Queue a request for the next state |
|
455 SelfComplete(); |
|
456 } |
|
457 |
|
458 // --------------------------------------------------------------------------- |
|
459 // CPdcEngine::Finish |
|
460 // Signals the completion of the state machine, either by completing the |
|
461 // caller's TRequestStatus or be stopping the active scheduler loop. |
|
462 // @param aError Any error on completion or KErrNone otherwise |
|
463 // --------------------------------------------------------------------------- |
|
464 // |
|
465 void CPdcEngine::Finish(TInt /*aError*/) |
|
466 { |
|
467 // The process of adding predefined contacts has finished. |
|
468 CActiveScheduler::Stop(); |
|
469 } |
|
470 |
|
471 // --------------------------------------------------------------------------- |
|
472 // CPdcEngine::DisplayErrorNoteL |
|
473 // Displays an error message based upon the current state of the engine. |
|
474 // @param aError error that has occurred |
|
475 // --------------------------------------------------------------------------- |
|
476 // |
|
477 void CPdcEngine::DisplayErrorNoteL(TInt aError, TInt aErrorPosition, |
|
478 TBool errorCannotReserve) |
|
479 { |
|
480 LOGTEXT(_L("DisplayErrorNoteL")); |
|
481 TInt resId = -1; |
|
482 |
|
483 if (errorCannotReserve) |
|
484 { |
|
485 resId = R_PDC_ERROR_RESERVE_ERROR; |
|
486 } |
|
487 |
|
488 switch (aErrorPosition) |
|
489 { |
|
490 case EDeleteOldContacts: |
|
491 { |
|
492 // Error deleting old contacts |
|
493 resId = R_CONTACT_DELETION_ERROR; |
|
494 } |
|
495 break; |
|
496 case EGettingFileLocation: |
|
497 { |
|
498 // Error getting the file location |
|
499 resId = R_FILELOCATION_ERROR; |
|
500 } |
|
501 break; |
|
502 case EReadingVCards: |
|
503 { |
|
504 // Error reading the vCards |
|
505 resId = R_VCARD_ERROR; |
|
506 } |
|
507 break; |
|
508 case EReadingXML: |
|
509 { |
|
510 // Error read the XML file |
|
511 resId = R_XML_ERROR; |
|
512 } |
|
513 break; |
|
514 case EUpdateData: |
|
515 { |
|
516 // Error persisting the data |
|
517 resId = R_STORE_ERROR; |
|
518 } |
|
519 break; |
|
520 case EFinish: |
|
521 default: |
|
522 { |
|
523 // Should never reach this point |
|
524 ASSERT( 0 ); |
|
525 } |
|
526 } |
|
527 |
|
528 TFileName fileName(KErrorResourceFile); |
|
529 CStringResourceReader* strings = CStringResourceReader::NewLC(fileName); |
|
530 |
|
531 TPtrC noteFormat; |
|
532 noteFormat.Set(strings->ReadResourceString(resId)); |
|
533 |
|
534 TBuf<128> noteText; |
|
535 noteText.Format(noteFormat, aError); |
|
536 |
|
537 // Create and display the error note |
|
538 CAknGlobalNote* globalNote = CAknGlobalNote::NewLC(); |
|
539 globalNote->ShowNoteL(EAknGlobalErrorNote, noteText); |
|
540 CleanupStack::PopAndDestroy(globalNote); |
|
541 CleanupStack::PopAndDestroy(strings); |
|
542 } |
|
543 |
|
544 // --------------------------------------------------------------------------- |
|
545 // CPdcEngine::StoreReady |
|
546 // from MVPbkContactStoreObserver |
|
547 // Called when the contact store is ready to be used, signals |
|
548 // the next engine state. |
|
549 // @param aContactStore The store that is ready. |
|
550 // --------------------------------------------------------------------------- |
|
551 // |
|
552 void CPdcEngine::StoreReady(MVPbkContactStore& /*aContactStore*/) |
|
553 { |
|
554 LOGTEXT(_L("StoreReady")); |
|
555 // If we are waiting for the contacts to be opened, self |
|
556 // complete when the store ready callback is received. |
|
557 if (iEngineState == EOpeningContacts) |
|
558 { |
|
559 // Set the next state |
|
560 iEngineState = EDeleteOldContacts; |
|
561 iDeletedStoredContact = EFalse; |
|
562 SelfComplete(); |
|
563 } |
|
564 } |
|
565 |
|
566 // --------------------------------------------------------------------------- |
|
567 // CPdcEngine::StoreUnavailable |
|
568 // from MVPbkContactStoreObserver |
|
569 // Called when a contact store becomes unavailable. |
|
570 // @param aContactStore The store that became unavailable. |
|
571 // @param aReason The reason why the store is unavailable. |
|
572 // This is one of the system wide error codes. |
|
573 // --------------------------------------------------------------------------- |
|
574 // |
|
575 void CPdcEngine::StoreUnavailable(MVPbkContactStore& /*aContactStore*/, |
|
576 TInt aReason) |
|
577 { |
|
578 |
|
579 // Self complete with the error reason. |
|
580 TRequestStatus* status = &iStatus; |
|
581 User::RequestComplete(status, aReason); |
|
582 SetActive(); |
|
583 } |
|
584 |
|
585 // --------------------------------------------------------------------------- |
|
586 // CPdcEngine::HandleStoreEventL |
|
587 // from MVPbkContactStoreObserver |
|
588 // Called when changes occur in the contact store. |
|
589 // IGNORED. |
|
590 // @param aContactStore A store whose event it is. |
|
591 // @param aStoreEvent The event that has occurred. |
|
592 // --------------------------------------------------------------------------- |
|
593 // |
|
594 void CPdcEngine::HandleStoreEventL(MVPbkContactStore& /*aContactStore*/, |
|
595 TVPbkContactStoreEvent /*aStoreEvent*/) |
|
596 { |
|
597 } |
|
598 |
|
599 // --------------------------------------------------------------------------- |
|
600 // CPdcEngine::DeleteStoredContactsL |
|
601 // Called when error occur iwhile reading XML or vcard file. |
|
602 // IGNORED. |
|
603 // --------------------------------------------------------------------------- |
|
604 // |
|
605 void CPdcEngine::DeleteStoredContactsL() |
|
606 { |
|
607 LOGTEXT(_L("DeleteStoredContactsL")); |
|
608 // Create the contacts deletion object |
|
609 delete iContactDeleter; |
|
610 iContactDeleter = NULL; |
|
611 |
|
612 iContactDeleter = CPdcContactDeletion::NewL( *iContactManager); |
|
613 iContactDeleter->DeleteStoredContactsL(iLinkArray, iStatus, |
|
614 iDeletedStoredContact); |
|
615 SetActive(); |
|
616 } |
|
617 |