contactextensions/predefinedcontacts/src/PdcEngine.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     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