--- a/srsf/nssvascontacthdlr/src/nssvasccontacthandlerimpl.cpp Mon Jan 18 20:20:30 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3429 +0,0 @@
-/*
-* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: Responsible for maintaining synchronization between the contact DB
-* and the VAS DB
-*
-*/
-
-
-/** @todo Read the whole contact in one go.
-
- Currently Contact handler usually opens the same contact (ReadContactL) two to
- three times in order to read its data (mostly often three times).
- One is in GetContactNickname
- Second in GetContactTitle
- Third in DoAddNamesL when deciding what number field should the voice tag
- be trained for
- If we could unite these reads, "reading contacts" phase will be 2-3 times faster.
- It would make about 10-20% improvement for the training of some 300 contacts */
-
-// INCLUDE FILES
-#include "nssvasccontacthandlerimpl.h"
-#include "nssvasctrainingparameters.h"
-#include <nssvascvasdbmgr.h>
-#include <centralrepository.h>
-#include <f32file.h>
-#include <bautils.h>
-#include <barsc.h>
-#include <barsread.h>
-#include <sysutil.h>
-#include "srsfprivatecrkeys.h"
-
-// Publish & Subscribe of the contact handler activity
-#include <nssvascoreconstant.h>
-
-#include <vascvpbkhandler.h>
-#include <featmgr.h>
-#include "nssvasdatasyncwatcher.h"
-#include "nsschbackupobserver.h"
-#include <StringLoader.h>
-#include <nssvascontacthandler.rsg>
-#include <data_caging_path_literals.hrh>
-#include "rubydebug.h"
-
-// CONSTANTS
-// Name of the context in the SIND DB. Voice tags for contacts are saved there
-_LIT( KNssCHNameDialContext, "NAMEDIAL" );
-
-// Languages which use lastname-firstname order
-const TLanguage KSwappedLanguages[] =
- {
- ELangHungarian, // 17
- ELangTaiwanChinese, // 29
- ELangHongKongChinese, // 30
- ELangJapanese, // 32
- ELangPrcChinese, // 31
- ELangKorean, // 65
- ELangVietnamese // 96
- };
-
-// Number of languages that use lastname-firstname order
-const TInt KNumberOfSwappedLanguages = sizeof( KSwappedLanguages ) / sizeof ( TLanguage );
-
-
-// Maximal number of retrials to save tags
-const TInt KVASCHMaxRetry = 2;
-
-// Size of the event 'pack'. Tags are added and deleted in groups.
-// KMaxNamesAtOnce is the maximal size of a group
-const TInt KMaxNamesAtOnce = 100;
-
-// Initial value of the time interval used to detect periodic action. In
-// microseconds. If KEventMomentsSize events happened within the
-// KInitialPeriodicActionInterval, we assume, that periodic action has started
-const TInt KInitialPeriodicActionInterval = 15000000;
-
-// Time interval used to periodically check if there are pending
-// events to process. In microseconds
-const TInt KPeriodicTimerInterval = 1000000;
-
-// If there are this many consecutive full resyncs initiated by errors during
-// handling normal changes (or during previous full resync), there is probably
-// something consistently wrong at the lower layers.
-// Full resync trials (and the whole contact handler) should be disabled until
-// reboot after KMaxConsecutiveErrorFullResync consecutive unsuccessful trials
-const TInt KMaxConsecutiveErrorFullResync = 2;
-
-// List of phonebook fields, that are supported by contact handler.
-// I.e. fields, that can be dialed and voice tagged
-/** @todo Consider using information from phonebook about which fields contain numbers
-and using the following lists for priorities only */
-const TPbkFieldId KTaggableFields[] =
- {
- EPbkFieldIdPhoneNumberMobile,
- EPbkFieldIdPhoneNumberGeneral,
- EPbkFieldIdPhoneNumberStandard,
- EPbkFieldIdPhoneNumberHome,
- EPbkFieldIdPhoneNumberWork,
- EPbkFieldIdPhoneNumberVideo,
- EPbkFieldIdVOIP,
- EPbkFieldIdXsp
- };
-const TInt KTaggableFieldsCount = sizeof( KTaggableFields ) / sizeof ( TPbkFieldId );
-
-// List of phonebook fields that are supported by video extension
-const TPbkFieldId KVideoExtensionFields[] =
- {
- EPbkFieldIdPhoneNumberVideo,
- EPbkFieldIdPhoneNumberMobile,
- EPbkFieldIdPhoneNumberGeneral,
- EPbkFieldIdPhoneNumberHome,
- EPbkFieldIdPhoneNumberWork
- };
-const TInt KVideoExtensionFieldsCount = sizeof( KVideoExtensionFields ) / sizeof ( TPbkFieldId );
-
-// List of phonebook fields that are supported by message extension
-const TPbkFieldId KMessageExtensionFields[] =
- {
- EPbkFieldIdPhoneNumberMobile,
- EPbkFieldIdPhoneNumberGeneral,
- EPbkFieldIdPhoneNumberHome,
- EPbkFieldIdPhoneNumberWork,
- EPbkFieldIdPhoneNumberVideo
- };
-const TInt KMessageExtensionFieldsCount = sizeof( KMessageExtensionFields ) / sizeof ( TPbkFieldId );
-
-// List of phonebook fields that are supported by VOIP extension
-const TPbkFieldId KVOIPExtensionFields[] =
- {
- EPbkFieldIdVOIP,
- EPbkFieldIdXsp
- };
-const TInt KVOIPExtensionFieldsCount = sizeof( KVOIPExtensionFields ) / sizeof ( TPbkFieldId );
-
-// Size of the client data per context. Is used to store the context language
-// In bytes
-const TInt KClientDataSize = sizeof(TNssContextClientData);
-
-
-// Number of retries to try to lock the same contact
-// 600 times should stand for 10 mins
-// -1 means trying forever
-const TInt KMaxContactLockRetrials = 600;
-
-// Interval between the ticks of the contact wait timer
-// in microseconds
-const TInt32 KContactWaitInterval = 1000000;
-
-// Bytes that should be free in the disk drive in addition to critical level
-// before operation is started (100kB)
-const TInt KIncreaseOfDatabaseSizes = 100000;
-
-// Define this if name free-order is enabled
-//#define NSSVAS_CONTACTHANDLER_FREEORDER
-// LOCAL FUNCTION DECLARATIONS
-
-
-// ================= MEMBER FUNCTIONS =======================
-
-
-#ifdef _DEBUG
-_LIT( KFile, "VasCContactHandlerImpl.cpp" );
-#endif
-
-/**
-* Is used in DoHandleEventFailedL to *asynchronously* simulate successful tag
-* deletion
-*/
-NONSHARABLE_CLASS( CSuccessfulDeletionSimulator ) : public CAsyncOneShot
- {
- public:
- CSuccessfulDeletionSimulator( CNssContactHandlerImplementation& aHost );
- ~CSuccessfulDeletionSimulator();
- protected:
- /** Is called by the system after we asked it to Call() closer
- */
- virtual void RunL();
- private:
- CNssContactHandlerImplementation& iHost;
- };
-
-// -----------------------------------------------------------------------------
-// CSuccessfulDeletionSimulator::~CSuccessfulDeletionSimulator
-// Destructor
-// -----------------------------------------------------------------------------
-//
-CSuccessfulDeletionSimulator::~CSuccessfulDeletionSimulator()
- {
- RUBY_DEBUG0( "~CSuccessfulDeletionSimulator" );
- if( IsAdded() )
- {
- RUBY_DEBUG0( "~CSuccessfulDeletionSimulator Request is still in progress, deque it" );
- Deque();
- }
- }
-
-// -----------------------------------------------------------------------------
-// CSuccessfulDeletionSimulator::CSuccessfulDeletionSimulator
-// Constructor
-// -----------------------------------------------------------------------------
-//
-CSuccessfulDeletionSimulator::CSuccessfulDeletionSimulator( CNssContactHandlerImplementation& aHost ) :
- CAsyncOneShot( CActive::EPriorityStandard ),
- iHost( aHost )
- {
- //nothing
- }
-
-// -----------------------------------------------------------------------------
-// CAppCloser::RunL
-// Will be called by the system and exits the application
-// -----------------------------------------------------------------------------
-//
-void CSuccessfulDeletionSimulator::RunL()
- {
- RUBY_DEBUG0( "CSuccessfulDeletionSimulator::RunL Start" );
- if( iStatus == KErrNone )
- {
- CArrayPtrFlat<MNssTag>* empty = new (ELeave) CArrayPtrFlat<MNssTag>( 1 );
- iHost.DoRemoveNamesAfterGetTagList( empty );
- // empty will be destroyed in the DoRemoveNamesAfterGetTagList
- }
- else
- {
- RUBY_ERROR1( "CSuccessfulDeletionSimulator::RunL Unexpected iStatus [%d]", iStatus.Int() );
- }
- RUBY_DEBUG0( "CSuccessfulDeletionSimulator::RunL End" );
- }
-
-
-
-// -----------------------------------------------------------------------------
-// CNssContactHandlerImplementation::CNssContactHandlerImplementation
-// C++ default constructor can NOT contain any code, that
-// might leave.
-// -----------------------------------------------------------------------------
-//
-CNssContactHandlerImplementation::CNssContactHandlerImplementation( )
-: iState( ECHInitializing ),
- iSeparator( KNameSeparator()[0] ),
- iEndOfPeriodicActionInterval( KInitialPeriodicActionInterval )
- {
- iClientData.iLanguage = ELangNone;
-
- // initialize last RestartTimer calls to be long ago in
- // the past (January 1st, 0 AD nominal Gregorian)
- for( TInt i = 0; i < KEventMomentsSize; i++)
- {
- iEventMoments[i] = 0;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CNssContactHandlerImplementation::ConstructL
-// EPOC second phase constructor can leave.
-// -----------------------------------------------------------------------------
-//
-void CNssContactHandlerImplementation::ConstructL()
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::ConstructL" );
-
- User::LeaveIfError( iFSession.Connect() );
-
- // Sets up TLS, must be done before FeatureManager is used.
- FeatureManager::InitializeLibL();
- iVoIPFeatureSupported = FeatureManager::FeatureSupported( KFeatureIdCommonVoip );
- iVideoCallFeatureSupported = FeatureManager::FeatureSupported( KFeatureIdCsVideoTelephony );
- // Frees the TLS! Must be done after FeatureManager is used.
- FeatureManager::UnInitializeLib();
-
- // Before enabling event, start monitoring the PC-suite state
- iSyncBackupWaiter = new (ELeave) CActiveSchedulerWait;
-
- iDataSyncWatcher = CNssDataSyncWatcherFactory::ConstructDataSyncWatcherL( *this );
-
- iBackupObserver = CNssChBackupObserver::NewL( *this );
-
- iContactWaiter = new (ELeave) CActiveSchedulerWait;
-
- iDeletionSimulator = new (ELeave) CSuccessfulDeletionSimulator( *this );
-
- EnableEventHandling();
-
- iEventArray.Reset(); // Ready to be used
-
- TInt errProp = iBusyProperty.Define( KSINDUID, ETrainingContactsState, RProperty::EInt );
- if( ( errProp != KErrNone ) && ( errProp != KErrAlreadyExists ) )
- {
- RUBY_ERROR1("CNssContactHandlerImplementation::ConstructL() Failed to define the property. Error [%d]",
- errProp);
- User::Leave( errProp );
- }
-
- // Publish contact handler as busy before the DB operations
- errProp = iBusyProperty.Attach( KSINDUID, ETrainingContactsState );
- if( errProp != KErrNone )
- {
- // KErrNotFound is also an error as we just defined the property
- RUBY_ERROR1("CNssContactHandlerImplementation::ConstructL() Failed to attach to property. Error [%d]",
- errProp);
- User::Leave( errProp );
- }
-
- errProp = iBusyProperty.Set( EContactsTraining );
- if ( errProp != KErrNone )
- {
- RUBY_ERROR1("CNssContactHandlerImplementation::ConstructL() Failed to set property. Error [%d]",
- errProp );
- User::Leave( errProp ) ;
- }
-
-
- // central repository
- iRepository = CRepository::NewL( KCRUidSRSFSettings );
- iRepositoryObserver = CCenRepNotifyHandler::NewL( *this, *iRepository,
- CCenRepNotifyHandler::EIntKey,
- KSRSFFullResyncNeeded );
- iRepositoryObserver->StartListeningL();
-
- //Get VAS DB manager
- iVasDbManager = CNssVASDBMgr::NewL();
- iVasDbManager->InitializeL();
- RUBY_DEBUG0( "CNssContactHandlerImplementation::ConstructL iVasDbManager initialized" );
-
- //Get Tag Manager and Context Manager interfaces
- iTagManager = iVasDbManager->GetTagMgr();
- iContextManager = iVasDbManager->GetContextMgr();
-
- // Prepare training parameters
- iTrainingParams = CNssTrainingParameters::NewL();
-
- RUBY_DEBUG0( "CNssContactHandlerImplementation::ConstructL iTrainingParams prepared" );
-
- // Set languages which have lastname-firstname order
- for ( TInt iCounter = 0; iCounter < KNumberOfSwappedLanguages; iCounter++ )
- {
- User::LeaveIfError( iSwappedLanguages.Append( KSwappedLanguages[iCounter] ) );
- }
-
-#ifdef __SINDE_TRAINING
- // Main array for languages
- RArray<RTrainingLanguageArray> languages;
-
- // Languages for names
- RArray<TLanguage> nameLanguages;
- User::LeaveIfError( nameLanguages.Append( User::Language() ) );
- User::LeaveIfError( nameLanguages.Append( ELangOther ) );
- User::LeaveIfError( languages.Append( nameLanguages ) );
-
- // Languages for extensions
- RArray<TLanguage> extLanguages;
- User::LeaveIfError( extLanguages.Append( User::Language() ) );
- User::LeaveIfError( languages.Append( extLanguages ) );
-
- // Store languages to training parameters
- iTrainingParams->SetSindeLanguages( languages );
-
- // Close arrays, iTrainingParams has done a copy of these
- extLanguages.Close();
- nameLanguages.Close();
- languages.Close();
-
-#else
- // Set the languages
- RArray<TLanguage> *languages = new (ELeave) RArray<TLanguage>;
- CleanupStack::PushL( languages );
- // Always generate a pronunciation in UI language
- User::LeaveIfError( languages->Append( User::Language() ) );
- // give some extra languages, which can be selected in engine
- User::LeaveIfError( languages->Append( ELangOther ) );
- iTrainingParams->SetLanguages( languages );
- CleanupStack::Pop( languages );
-#endif
-
- // The separator between the first name and the last name
- iTrainingParams->SetSeparator( iSeparator );
-
-#ifdef __SIND_EXTENSIONS
-
- ReadExtensionsL();
-#endif // __SIND_EXTENSIONS
-
- ConnectToPhonebookL();
-
- TLitC<9> name = KNssCHNameDialContext;
-
- // Get context.
-
- // (1) if we have synced earlier -> we have created a context, and saved the language
- // (2) if we haven't synced -> we need to create context
- //
- // In case (2), GetContext fails.
- // We'll assume that GetContext is successful until it fails.
- iHaveWeEverSynced = ETrue;
-
- TInt err = iContextManager->GetContext( this, name );
- RUBY_DEBUG1( "CNssContactHandlerImplementation::ConstructL Requested GetContext. err [%d]", err);
-
- if ( err != KErrNone )
- {
- // The same function is called, whether GetContext fails synchronously
- // or asynchronously.
- GetContextCompleted( NULL, KErrNotFound );
- }
- iDeleteTagListArray = new (ELeave) CArrayPtrFlat<MNssTag>(50);
-
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::NewL
-// Two-phased constructor.
-// ---------------------------------------------------------
-//
-CNssContactHandlerImplementation* CNssContactHandlerImplementation::NewL( )
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::NewL" );
- CNssContactHandlerImplementation* self = new (ELeave) CNssContactHandlerImplementation();
-
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop( self );
-
- return self;
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::~CNssContactHandlerImplementation
-// Destructor
-// ---------------------------------------------------------
-//
-CNssContactHandlerImplementation::~CNssContactHandlerImplementation()
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::~CNssContactHandlerImplementation FIXED" );
-
- iFSession.Close();
-
- iEventArray.Close(); // Close the RArray
-
- delete iDataSyncWatcher;
- delete iBackupObserver;
-
- if ( iSyncBackupWaiter != NULL )
- {
- if( iSyncBackupWaiter->IsStarted() )
- {
- iSyncBackupWaiter->AsyncStop();
- }
- }
- delete iSyncBackupWaiter;
-
- if ( iContactWaiter != NULL )
- {
- if( iContactWaiter->IsStarted() )
- {
- iContactWaiter->AsyncStop();
- }
- }
-
-
- delete iContactWaiter;
- delete iDeletionSimulator;
- delete iPeriodicHandleEventTimer;
-
- delete iContext;
-
- delete iVasDbManager;
- RProperty::Delete( KSINDUID, ETrainingContactsState );
- iBusyProperty.Close();
-
- delete iRepositoryObserver;
- delete iRepository;
-
- delete iTrainingParams;
- iTagArray.ResetAndDestroy();
-
- for( TInt k( 0 ); k < iContactQueue.Count(); k++ )
- {
- delete iContactQueue[k].iTitle;
- }
- iContactQueue.Close();
-
- iDelList.Close();
- iAddList.Close();
- iRemoveIconList.Close();
- iVoiceTagAddedList.Close();
- iSwappedLanguages.Close();
-
- DisconnectFromPhonebook();
-
-#ifdef __SIND_EXTENSIONS
-
- for ( TInt i(0); i < iExtensionList.Count(); i++ )
- {
- delete iExtensionList[i].iText;
- }
-
- iExtensionList.Close();
-#endif // __SIND_EXTENSIONS
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::HandleEventL
-// Called by phonebook handler when a contact database event
-// occurs
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::HandleEventL( const TPhonebookEvent& aEvent )
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::HandleEventL" );
- RUBY_DEBUG2( "CNssContactHandlerImplementation::HandleEventL(). Contact id [%d], event type [%d]", aEvent.iContactId, aEvent.iType );
-
- if ( aEvent.iType == EContactChanged ||
- aEvent.iType == EContactDeleted ||
- aEvent.iType == EContactAdded ||
- aEvent.iType == EUnknownChanges )
- {
- if( !CausedByVoiceTagAddition( aEvent ) )
- {
- // Check if operations can be finished
- // There should be enough disk space
- if ( NoDiskSpace() )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::HandleEventL not enough disk space, disabling event handling" );
- DisableEventHandling();
- }
- else
- {
- TInt errProp = iBusyProperty.Set( EContactsTraining );
- if ( errProp != KErrNone )
- {
- RUBY_ERROR1("CNssContactHandlerImplementation::ConstructL() Failed to set property. Error [%d]",
- errProp );
- User::Leave( errProp ) ;
- }
- UpdatePeriodicActionVars();
- iEventArray.Append( aEvent );
-
- if ( iState == ECHIdle )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::HandleEventL() iState == ECHIdle => DoHandleEvent" );
-
- // Process the first new event from the queue
- TRAPD( err, DoHandleEventsL() );
- RUBY_DEBUG1( "CNssContactHandlerImplementation::HandleEventL. Assert would fail and Panic IF err != KErrNone. err [%d]", err );
- RUBY_ASSERT_DEBUG( err == KErrNone, User::Panic( KFile, __LINE__ ) );
-
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::HandleEventL. Error [%d] in DoHandleEventsL", err );
- }
- }
- else
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::HandleEventL() iState == [%d] => Do not handle the event right now", iState );
- } // if iState else
- }
- } // if caused be voice tag addition
- else
- {
- RUBY_DEBUG2( "CNssContactHandlerImplementation::HandleEventL(). Event for Contact id [%d] was caused by a voice icon addition and will be ignored, eventArray size [%d]", aEvent.iContactId, iEventArray.Count() );
- if ( ( iVoiceTagAddedList.Count() == 0 ) && ( iState == ECHIdle ) && ( iEventArray.Count() == 0 ) )
- {
- RUBY_DEBUG0( "HandleEventL No more voice icon events expected, nothing pending." );
- }
- else
- {
- RUBY_DEBUG1( "HandleEventL [%d] voice icon events are still expected", iVoiceTagAddedList.Count() );
- }
- }
- }
- else if ( aEvent.iType == EStoreRestoreBeginning )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::HandleEventL restore begin" );
- iRestoreRunning = ETrue; // set to differentiate ending of restore or backup
- }
- else if ( aEvent.iType == EStoreBackupRestoreCompleted && iRestoreRunning )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::HandleEventL restore end" );
- // Set value to make full resync
- SetFullResyncCrFlagL( ETrue );
- iRestoreRunning = EFalse;
- } // if event type
- }
-
-
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoHandleEventL
-// Process the Event from phonebook
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoHandleEventsL()
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::DoHandleEventsL" );
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoHandleEventsL, eventArray size [%d]", iEventArray.Count() );
-
- // If there is no lengthy higher level routine executed
- if( !PeriodicAction() )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventsL !PeriodicAction()" );
- if ( iHandlerEnabled )
- {
- if ( IsFullResyncNeeded() )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventsL() Full resync if needed. Setting iState to ECHFullResync" );
- SetState( ECHFullResync );
-
- iEventArray.Close();
-
- FullResyncStart();
- }
- else
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventsL() Full resync if NOT needed. Setting iState to ECHHandlingNormalChanges" );
- SetState( ECHHandlingNormalChanges );
-
- // There are 3 phases in handling events:
- // (1) Make two lists:
- // * Names to be added
- // * Names to be deleted
- CollectAddRemoveListsL();
-
- // (2) Delete the names to be deleted. This operation is asynchronous.
- DoRemoveNamesL();
-
- // (3) After removing names, add the names to be added.
- // DoRemoveNamesL() starts the step (3)
- }
- }
- else
- {
- // In UREL, empty "else" branch will be eliminated by the compiler
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventsL() Handler was disabled" );
- }
-
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventsL() completed" );
-
- }// if !PeriodicAction
-
- else
- {
- // In UREL, empty "else" branch will be eliminated by the compiler
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventsL PeriodicAction detected, DoHandleEventsL omitted" );
- }
-
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DeleteTagCompleted
-// Called when the deletion of a tag is completed successfully
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DeleteTagCompleted( TInt aErrorCode )
- {
- if( aErrorCode == KErrNone )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DeleteTagCompleted. Assert iState == ECHHandlingNormalChanges. iState [%d]", iState);
- RUBY_ASSERT_DEBUG( iState == ECHHandlingNormalChanges, User::Panic( KFile, __LINE__ ) );
- }
- else
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DeleteTagCompleted: tag deletion failed" );
-
- iNormalChangesError = aErrorCode;
- }
-
- DoRemoveNamesAfterDeleteTagCompleted();
- }
-
-// -----------------------------------------------------------------
-// CNssContactHandlerImplementation::GetTagCompleted
-// Called by tag manager when getting of a tag list completes
-// -----------------------------------------------------------------
-//
-void CNssContactHandlerImplementation::GetTagListCompleted(
- MNssTagListArray* aTagList, TInt aErrorCode )
- {
- if( aErrorCode == KErrNone )
- {
- if ( iState == ECHHandlingNormalChanges )
- {
- DoRemoveNamesAfterGetTagList( aTagList );
- }
- else
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::GetTagListCompleted : Unknown state(%d)\n", iState );
- }
- }
- else
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::GetTagListCompleted. Error [%d]", aErrorCode );
-
- TRAPD( err, DoHandleEventFailedL() ); // Process the event fail
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::GetTagFailed. Error [%d] in DoHandleEventFailedL", err );
- }
- }
- }
-
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DisableEventHandling
-// Disables the event handling. Is used in case of unrecoverable error
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DisableEventHandling()
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DisableEventHandling" );
- iHandlerEnabled = EFalse;
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::EnableEventHandling
-// Enables event handling
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::EnableEventHandling()
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::EnableEventHandling" );
- iHandlerEnabled = ETrue;
- }
-
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::GetContextListCompleted
-// Called by tag manager when GetContextList() completes successfully
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::GetContextListCompleted(
- MNssContextListArray* /*aContextList*/, TInt /*aErrorCode*/ )
- {
- RUBY_ERROR0( "CNssContactHandlerImplementation::GetContextListCompleted - this function should never be called." );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::CheckErrorSigns
-// Compares client data (saved in VAS context)
-// to state of the phonebook to find out if
-// full synchronization is needed.
-//
-// If full resync is needed initiates it by saving into the event queue
-// special 'full resync event'
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::CheckErrorSigns()
- {
-
- RUBY_DEBUG0( "CNssContactHandlerImplementation::CheckErrorSigns" );
- TBool errorFound( EFalse );
- // Full resync, if this is the first time we launch.
- // if the UI language has changed.
- // if VAS Db and Contact Db time stamps do not match
- if ( iClientData.iLanguage == ELangNone ||
- iClientData.iLanguage != User::Language() )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::CheckErrorSigns language changed." );
- errorFound = ETrue;
- }
- else
- {
- // check that is full resyncronization needed
- iRepository->Get( KSRSFFullResyncNeeded, errorFound );
- }
-
- if ( errorFound )
- {
- TPhonebookEvent event;
- event.iType = ENullEvent;
- event.iContactId = 0;
-
- if ( iEventArray.Append( event ) != KErrNone )
- {
- RUBY_ERROR0( "CNssContactHandlerImplementation::CheckErrorSigns Failed to append to iEventArray" );
- }
- }
-
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::GetContextCompleted
-// Called by tag manager, when GetContext() completes successfully
-//
-// Depending on the contact handler state, continues full resync sequence or
-// sets the idle state
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::GetContextCompleted(
- MNssContext* aContext, TInt aErrorCode )
- {
- if( aErrorCode == KErrNone )
- {
- RUBY_ASSERT_DEBUG( iState == ECHInitializing || iState == ECHFullResync,
- User::Panic( KFile, __LINE__ ) );
-
- RUBY_DEBUG0( "CNssContactHandlerImplementation::GetContextCompleted" );
- iContext = aContext;
- TRAPD(err,
-
- iClientData.InternalizeL( iContext->ClientData() );
-
- if ( iState == ECHInitializing )
- {
- // If there are warning sings of error,
- // do full resynchronization.
- CheckErrorSigns();
-
- SetState( ECHIdle );
- RUBY_DEBUG0( "CNssContactHandlerImplementation::GetContextCompleted. Setting iState to ECHIdle" );
-
- if ( iEventArray.Count() ) // Verify whether more events in the queue
- {
-
- RUBY_DEBUG1( "CNssContactHandlerImplementation::GetContextCompletedhere are still [%d] events in the queue. Call DoHandleEvents for them", iEventArray.Count() );
-
- DoHandleEventsL(); // Process the 1st new event from the queue
- }
- }
- else if ( iState == ECHFullResync )
- {
- TRAPD( error, FullResyncCreateChangesL() );
- if( error != KErrNone )
- {
- RUBY_ERROR1( "FullResyncCreateChangesL failed with [%d]. Panic, nothing can be done", error );
- RUBY_ASSERT_DEBUG( EFalse, User::Panic( KFile, __LINE__ ) );
- }
- }
- else
- {
- RUBY_ERROR0( "CNssContactHandlerImplementation::GetContextCompleted Unexpected state" );
- RUBY_ASSERT_DEBUG( EFalse, User::Panic( KFile, __LINE__ ) );
- }
- ); // TRAPD
- if( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::GetContextCompleted Leaves with [%d] inside", err );
- }
- RUBY_DEBUG0( "CNssContactHandlerImplementation::GetContextCompleted completed" );
- }
-
- else // aErrorCode != KErrNone
- {
- RUBY_ASSERT_DEBUG( iState == ECHInitializing || iState == ECHFullResync,
- User::Panic( KFile, __LINE__ ) );
-
- if ( iState == ECHInitializing )
- {
- iHaveWeEverSynced = EFalse;
- SetState ( ECHFullResync );
- FullResyncStart();
- }
- }
-
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::SaveContextCompleted
-// Called when SaveContext() completes successfully
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::SaveContextCompleted( TInt aErrorCode )
- {
- if( aErrorCode == KErrNone )
- {
- RUBY_ASSERT_DEBUG( iState == ECHInitializing ||
- iState == ECHFullResync,
- User::Panic( KFile, __LINE__ ) );
-
- iHaveWeEverSynced = ETrue;
-
- if ( iState == ECHInitializing )
- {
- // Retrive the Context to get the new ContextId from VasDB
- iContextManager->GetContext( this, KNssCHNameDialContext );
- }
- else if ( iState == ECHFullResync )
- {
- TRAPD( error, FullResyncCreateChangesL() );
- if ( error != KErrNone )
- {
- RUBY_ERROR1( "SaveContextCompleted Failed to create full resync changes. Critical error [%d]",
- error );
- DisableEventHandling();
- } // if error != KErrNone
- } // else if ( iState == ECHFullResync )
- else
- {
- // we should never be here, because the condition is checked
- // by ASSERT_DEBUG at the start of the function
- RUBY_ERROR0( "CNssContactHandlerImplementation::SaveContextCompleted Unexpected state!" );
- }
- }
-
- else // aErrorCode != KErrNone
- {
- // Failed to initialize will collect the events forever and will never process them
- // Will try to initialize again after reboot
- RUBY_ERROR0( "CNssContactHandlerImplementation::SaveContextCompleted failed. Staying forever in ECHFullResync" );
- RUBY_ERROR0( "CNssContactHandlerImplementation::SaveContextCompleted failed. Reboot to try initializing again" );
- DisableEventHandling();
- }
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::SaveTagCompleted
-// Called when SaveTag() completes
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::SaveTagCompleted( TInt aErrorCode )
- {
- RUBY_ASSERT_DEBUG( iState == ECHHandlingNormalChanges, User::Panic( KFile, __LINE__ ) );
-
- DoAddNamesSaveTagCompleted( aErrorCode );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::GetContactTitleL
-// Populates aTitle with either "FirstName LastName" or "CompanyName".
-// "CompanyName" is given only if both First and Last names are missing.
-//---------------------------------------------------------
-//
-HBufC* CNssContactHandlerImplementation::GetContactTitleL( TContactItemId aContactId,
- TBool aUseDefaultOrder,
- TBool& aBothFirstAndLastFound,
- TVasTagType& aTagType )
- {
- RUBY_DEBUG_BLOCKL( "CNssContactHandlerImplementation::GetContactTitleL" );
- // Find out if lastname-firstname should be used
- TBool useLastFirstOrder = EFalse;
-
- // By default, this function returns firstname and/or lastname
- aTagType = ETagTypeName;
-
- if ( aUseDefaultOrder )
- {
- useLastFirstOrder = SwapNameOrder();
- }
- else
- {
- useLastFirstOrder = !SwapNameOrder();
- }
- WaitUntilNoSyncBackupIsRunning();
- ReadContactL( aContactId );
-
- HBufC* firstNameText = NULL;
- HBufC* lastNameText = NULL;
- HBufC* companyNameText = NULL;
-
- TInt firstLength( 0 );
- TInt lastLength( 0 );
- TInt companyLength( 0 );
-
- TInt error = KErrNone;
-
- // name reading fields are used in Japanese
- TRAP( error, iPbkHandler->FindFieldL( EPbkFieldIdFirstNameReading ) );
- if ( error == KErrNotFound )
- {
- // not found
- TRAP( error, iPbkHandler->FindFieldL( EPbkFieldIdFirstName ) );
- }
-
- if ( error == KErrNone )
- {
- firstNameText = iPbkHandler->TextL().AllocLC();
- TrimName( firstNameText );
- firstLength = firstNameText->Length();
- if ( firstLength == 0 )
- {
- CleanupStack::PopAndDestroy( firstNameText );
- firstNameText = NULL;
- }
- }
-
- TRAP( error, iPbkHandler->FindFieldL( EPbkFieldIdLastNameReading ) );
- if ( error == KErrNotFound )
- {
- // not found
- TRAP( error, iPbkHandler->FindFieldL( EPbkFieldIdLastName ) );
- }
-
- if ( error == KErrNone )
- {
- lastNameText = iPbkHandler->TextL().AllocLC();
- TrimName( lastNameText );
- lastLength = lastNameText->Length();
- if ( lastLength == 0 )
- {
- CleanupStack::PopAndDestroy( lastNameText );
- lastNameText = NULL;
- }
- }
-
- TRAP( error, iPbkHandler->FindFieldL( EPbkFieldIdCompanyName ) );
-
- if ( error == KErrNone )
- {
- companyNameText = iPbkHandler->TextL().AllocLC();
- TrimName( companyNameText );
- companyLength = companyNameText->Length();
- if ( companyLength == 0 )
- {
- CleanupStack::PopAndDestroy( companyNameText );
- companyNameText = NULL;
- }
- }
-
- // Use third parameter to return a flag if both lastname and firstname are found
- if ( ( firstLength > 0 ) && ( lastLength > 0 ) )
- {
- aBothFirstAndLastFound = ETrue;
- }
- else
- {
- aBothFirstAndLastFound = EFalse;
- }
-
- HBufC* title( NULL );
-
-#ifdef __SIND_EXTENSIONS
- if ( firstLength + lastLength > 0 )
- {
- TInt spaceForIndexes( 0 );
- // Find out how much more space is needed for "training indexes"
- if ( aBothFirstAndLastFound )
- {
- spaceForIndexes = 2 * KTrainingIndexSize;
- }
- else
- {
- spaceForIndexes = KTrainingIndexSize;
- }
-
- title = HBufC::NewL( firstLength + lastLength + spaceForIndexes );
-
- // Check the order
- if ( useLastFirstOrder )
- {
- // Lastname-firstname
- if ( lastNameText )
- {
- AppendName( title, lastNameText );
- }
-
- if ( firstNameText )
- {
- AppendName( title, firstNameText );
- }
- }
- else
- {
- // Firstname-lastname
- if ( firstNameText )
- {
- AppendName( title, firstNameText );
- }
-
- if ( lastNameText )
- {
- AppendName( title, lastNameText );
- }
- }
- }
- // Try company name, if the personal name fails.
- else if ( companyLength > 0 )
- {
- aTagType = ETagTypeCompanyName;
- title = HBufC::NewL( companyLength + KTrainingIndexSize );
- AppendName( title, companyNameText );
- }
-#else
- // Use personal name, if there is one.
- if ( firstLength + lastLength > 0 )
- {
- title = HBufC::NewL( firstLength + 1 + lastLength );
-
- // Check the order
- if ( useLastFirstOrder )
- {
- // Lastname-firstname
- if ( lastNameText )
- {
- title->Des().Append( lastNameText->Des() );
-
- if ( firstNameText )
- {
- // Separator marker
- title->Des().Append( iSeparator );
- }
- }
-
- if ( firstNameText )
- {
- title->Des().Append( firstNameText->Des() );
- }
-
-
- }
- else
- {
- // Firstname-lastname
- if ( firstNameText )
- {
- title->Des().Append( firstNameText->Des() );
-
- if ( lastNameText )
- {
- // Separator marker
- title->Des().Append( iSeparator );
- }
- }
-
- if ( lastNameText )
- {
- title->Des().Append( lastNameText->Des() );
- }
-
- }
- }
- // Try company name, if the personal name fails.
- else if ( companyLength > 0 )
- {
- aTagType = ETagTypeCompanyName;
- title = HBufC::NewL( companyLength );
- title->Des().Append( companyNameText->Des() );
- }
-#endif // __SIND_EXTENSIONS
- // It is possible to make a contact without a name.
- else
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::ContactTitle: No name, ContactId=[%d]" , aContactId );
- }
-
- if ( companyNameText )
- {
- CleanupStack::PopAndDestroy( companyNameText );
- }
-
- if ( lastNameText )
- {
- CleanupStack::PopAndDestroy( lastNameText );
- }
-
- if ( firstNameText )
- {
- CleanupStack::PopAndDestroy( firstNameText );
- }
-
- return title;
- }
-
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::SwapNameOrder
-// Returns ETrue if name order for current UI language should
-// be lastname-firstname, EFalse otherwise
-//---------------------------------------------------------
-//
-TBool CNssContactHandlerImplementation::SwapNameOrder()
- {
- // Find UI language
- TLanguage uiLanguage = User::Language();
-
- if ( iSwappedLanguages.Find( uiLanguage ) == KErrNotFound )
- {
- return EFalse;
- }
- else
- {
- return ETrue;
- }
- }
-
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::GetContactNicknameL
-// Returns nickname for a given contact
-//---------------------------------------------------------
-//
-HBufC* CNssContactHandlerImplementation::GetContactNicknameL( TContactItemId aContactId )
- {
- RUBY_DEBUG_BLOCKL( "CNssContactHandlerImplementation::GetContactNicknameL" );
- WaitUntilNoSyncBackupIsRunning();
- ReadContactL( aContactId );
-
- // Get the nick name
- iPbkHandler->FindFieldL( EPbkFieldIdSecondName );
-
- // Get the length of the additional name.
- TInt nickLength = iPbkHandler->TextL().Length();
-
- HBufC* title = NULL;
-
-#ifdef __SIND_EXTENSIONS
- // Use personal name, if there is one.
- if ( nickLength > 0 )
- {
- title = HBufC::NewL( nickLength + KTrainingIndexSize );
-
- HBufC* nickName = iPbkHandler->TextL().AllocL();
- TrimName( nickName );
- AppendName( title, nickName );
- delete nickName;
- }
-#else
- // Use personal name, if there is one.
- if ( nickLength > 0 )
- {
- title = HBufC::NewL( nickLength );
- title->Des().Append( iPbkHandler->TextL() );
- }
-#endif // __SIND_EXTENSIONS
-
- return title;
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoHandleEventFailed
-// Routine to process when handling the contact event failed
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoHandleEventFailedL()
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventFailedL start" );
-
- // Errors are normal if user deletes contact without a voice tag
- // E.g. because this contact had no number
- if( ( iDeleteTagListArray != NULL ) && ( iDeleteTagListArray->Count() > 0 ) )
- {
- // simulate successful deletion, just return no tags for further deletions
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventFailedL Deletion failed. Simulating successful empty deletion" );
- iDeletionSimulator->Call();
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventFailedL Called deletion simulator" );
- }
- else
- {
-
- // Try full resync couple of times. If still fails, stop contact handler.
- // When the phone is booted for the next time, try resyncing again
- if( iConsecutiveErrorFullResync < KMaxConsecutiveErrorFullResync )
- {
- iConsecutiveErrorFullResync++;
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoHandleEventFailedL Trying full resync for the [%d] time", iConsecutiveErrorFullResync);
- // clean structures that might be already full
- iTagArray.ResetAndDestroy();
-
- for( TInt k( 0 ); k < iContactQueue.Count(); k++ )
- {
- delete iContactQueue[k].iTitle;
- }
- iContactQueue.Close();
-
- iDelList.Close();
- iAddList.Close();
- iVoiceTagAddedList.Close();
- // generate full resync event
- TPhonebookEvent event;
- event.iType = ENullEvent;
- event.iContactId = 0;
- iEventArray.Insert( event, 0 );
- // will start full resync
- iTagArray.ResetAndDestroy();
- iSaveCallbackCounter = 0; // simulate completed action
- RUBY_DEBUG0( "DoHandleEventFailedL No leaving in the FullResync branch, retrying" );
- DoHandleEventsL(); // No leaving in the FullResync branch
- }
- else
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DoHandleEventFailedL Tried full resync for %d times. Disabling contact handler until reboot", KMaxConsecutiveErrorFullResync );
- // Tried several consecutive resyncs, didn't help
- // Disable itself until reboot
- DisableEventHandling();
- }
- } // if deletion else
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoHandleEventFailedL end" );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::PhonebookOrder
-// TLinearOrder comparison function for sorting phonebook events
-// according to their Phonebook ID.
-//---------------------------------------------------------
-//
-TInt CNssContactHandlerImplementation::PhonebookOrder( const TPhonebookEvent& a1, const TPhonebookEvent& a2 )
- {
- if ( a1.iContactId != a2.iContactId )
- {
- return( a1.iContactId - a2.iContactId );
- }
-
- if ( a1.iTime < a2.iTime )
- {
- return( -1 );
- }
- else if ( a1.iTime > a2.iTime )
- {
- return( 1 );
- }
- else{
- return( 0 );
- }
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::IsFullResyncNeeded
-// Checks if the event queue contains an event, which
-// launches full resynchronization. If it does, there is
-// no point in processing the other events.
-// ---------------------------------------------------------
-//
-TBool CNssContactHandlerImplementation::IsFullResyncNeeded()
- {
- for( TInt k( 0 ); k < iEventArray.Count(); k++ )
- {
- // Null event is used inside contact handler to signal full resync.
- if ( iEventArray[k].iType == ENullEvent
- || iEventArray[k].iType == EStoreBackupRestoreCompleted
- || iEventArray[k].iType == EUnknownChanges )
- {
- return ETrue;
- }
- }
-
- return EFalse;
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::CollectAddRemoveListsL
-// Given a list of Contact DB Events, this function compiles
-// a list of ids to-be-deleted and ids to-be-added.
-// A Contact DB Event contains:
-// * Contact ID
-// * Event type (added, modified, removed)
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::CollectAddRemoveListsL()
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::CollectAddRemoveListsL" );
- RUBY_DEBUG1( "CNssContactHandlerImplementation::CollectAddRemoveListsL(). iEventArray.Count [%d]", iEventArray.Count() );
- TInt k( 0 );
-
- RUBY_ASSERT_DEBUG( iAddList.Count() == 0, User::Panic( KFile, __LINE__ ) );
- RUBY_ASSERT_DEBUG( iDelList.Count() == 0, User::Panic( KFile, __LINE__ ) );
-
- // We collect two lists:
- // * Contacts to be deleted.
- // * Contacts to be added.
-
- TLinearOrder<TPhonebookEvent> order( PhonebookOrder );
-
- // Sort events according to the phonebook ID. This way, the events
- // modifying the same name are sequentially.
- iEventArray.Sort( order );
-
-
- // If several events happen for the same contact, fuse them into one event.
- for ( k = 0; k < iEventArray.Count() - 1; k++ )
- {
- if ( iEventArray[k].iContactId == iEventArray[k+1].iContactId )
- {
- // Sorting should have preserved the order of the events
- RUBY_ASSERT_DEBUG(iEventArray[k+1].iTime >= iEventArray[k].iTime, User::Panic( KFile, __LINE__ ) );
- RUBY_DEBUG1( "CNssContactHandlerImplementation::CollectAddRemoveListsL(). Fusing events for ContactId [%d]", iEventArray[k].iContactId );
- iEventArray[k+1].iType = EContactChanged;
- iEventArray.Remove( k );
-
- // We have removed an element
- k--;
- }
- }
-
- RUBY_DEBUG1( "CNssContactHandlerImplementation::CollectAddRemoveListsL(). Events sorted and fused iEventArray.Count [%d]", iEventArray.Count() );
-
- for( k = 0; k < iEventArray.Count() && k < KMaxNamesAtOnce; k++ )
- {
- TPhonebookEvent* event = &iEventArray[k];
-
- switch ( event->iType )
- {
- case EContactChanged:
- {
- // events caused by saving voice tag field are skipped
- // earlier, in HandleDatabaseEventL
-
- // We need to delete the old name
- User::LeaveIfError( iDelList.Append( *event ) );
- // and after that, add the new name.
- User::LeaveIfError( iAddList.Append( *event ) );
- break;
- }
- case EContactDeleted:
- {
- User::LeaveIfError( iDelList.Append( *event ) );
- break;
- }
- case EContactAdded:
- {
- User::LeaveIfError( iAddList.Append( *event ) );
- break;
- }
- default:
- RUBY_ERROR1( "CNssContactHandlerImplementation::CollectAddRemoveListsL() Unkown event type: %d", event->iType );
- break;
- }
- }
-
- if ( k < KMaxNamesAtOnce )
- {
- iEventArray.Close();
- }
- else
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::CollectAddRemoveListsL(). k >= KMaxNamesAtOnce [%d]. Deleting first KMaxNamesAtOnce events, they've been sorted into corresponding lists already",
- KMaxNamesAtOnce);
- for ( k = 0; k < KMaxNamesAtOnce; k++ )
- {
- iEventArray.Remove(0);
- }
- }
- RUBY_DEBUG1( "CNssContactHandlerImplementation::CollectAddRemoveListsL() iEventArray.Count [%d]",
- iEventArray.Count());
- RUBY_DEBUG2( "CNssContactHandlerImplementation::CollectAddRemoveListsL iDelList.Count() [%d], iAddList.Count() [%d]", iDelList.Count(), iAddList.Count());
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoRemoveNamesL
-// Starts name removal sequence
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoRemoveNamesL()
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::DoRemoveNamesL" );
- if ( iDelList.Count() == 0 )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesL Nothing to delete - skipping" );
-
- RemovingNamesCompletedL();
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesL completed early <= nothing to remove" );
- return;
- }
-
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesL - removing" );
-
- // we have: a list of tag IDs, which should be removed
- // we need: a list of tags, which should be removed.
-
- // First, we get the tags which correspond to the tag ids.
- // We need k async calls to VAS,
- // where k is the number of tag ids in iDelList.
- // We get a list of k' tags, where k' >= k.
- // If some tag has both proper name and a nickname, then k' > k.
-
- iContactId = iDelList[0].iContactId;
-
- if ( iDeleteTagListArray )
- {
- iDeleteTagListArray->ResetAndDestroy();
- }
- else
- {
- iDeleteTagListArray = new (ELeave) CArrayPtrFlat<MNssTag>(50);
- }
-
- TInt retCode = iTagManager->GetTagList( this, iContext, iContactId, 0 );
-
- if ( retCode != KErrNone )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesL failed to GetTagList" );
- // In the case of change event, try to add names even though they are not found
- // Might happen in scenario like this:
- // 1. User adds a name without any phone number -> no voice tag is created
- // 2. Contact is modified by adding a phone number
- iDelList.Close();
- DoAddNamesL();
- }
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesL completed" );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList
-// If contact database announces that n contacts need to be
-// deleted, we do n calls to GetTagList (the first is from DoRemoveNamesL).
-// Each callback returns 1 or more tags (name + nickname = 2 tags).
-// This function processes the callbacks by adding the tags to the
-// to-be-deleted list.
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList( MNssTagListArray* aTagList )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList. iState [%d]", iState );
-
- if ( iDelList.Count() == 0 )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList iDelList.Count() == 0" );
- }
-
- // Sieve out "false" tags: Those which have a wrong contact ID.
- /** Why? Maybe user was fast enough to delete these contacts from the phonebook
- * Anyway, why should we keep "false" tags in our db?
- */
- for ( TInt i=0; i < aTagList->Count(); i++ )
- {
- CArrayFixFlat<TInt>* intArray = aTagList->At(i)->RRD()->IntArray();
-
- RUBY_ASSERT_DEBUG( intArray->Count() > 0, User::Panic( KFile, __LINE__ ) );
-
- if ( intArray->At(0) != iContactId )
- {
- RUBY_ERROR2( "DoRemoveNamesAfterGetTagList expected contact id %d, but got contact id: %d", iContactId, intArray->At(0) );
- delete aTagList->At( i );
- aTagList->Delete( i );
- }
- }
-
- TRAPD( err, // trapping is a fix to make the function non-leaving
-
- // Add the tags to the to-be-deleted list.
- // (there are 1 or 2 tags in aTagList depending on
- // whether nickname is also there or not)
- for ( TInt k( 0 ); k < aTagList->Count(); k++ )
- {
- iDeleteTagListArray->AppendL( (*aTagList)[k] );
- }
-
- // We have processed this ID
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList Before removal. iDelList.Count [%d]", iDelList.Count() );
- if( iDelList.Count() > 0 )
- {
- iDelList.Remove( 0 );
- }
- else
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList Empty iDelList!" );
- }
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList After removal. iDelList.Count [%d]", iDelList.Count() );
-
- // If there are still more IDs, convert the next ID into a tag.
- if ( iDelList.Count() > 0 )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList There are [%d] contacts to delete. Calling GetTagList for them", iDelList.Count() );
- iContactId = iDelList[0].iContactId;
-
- TInt retCode
- = iTagManager->GetTagList( this, iContext, iContactId, 0 );
-
- if ( retCode != KErrNone )
- {
- RUBY_DEBUG0( "DoRemoveNamesAfterGetTagList Failed to GetTagList, going to DoHandleEventFailedL" );
- TRAP_IGNORE( DoHandleEventFailedL() ); // to handle the process event failed
- /** @todo reengineer into single return path */
- // Destroy tag list
- aTagList->Reset();
- delete aTagList;
- aTagList = 0;
- return;
- }
- }
-
- // If we just finished converting the last ID, move to the next phase.
- else{
- RUBY_DEBUG0( "DoRemoveNamesAfterGetTagList Moving to the next phase" );
- DoRemoveNamesCallDeleteTag();
- }
- ); // TRAPD
- if( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DoRemoveNamesAfterGetTagList Leaves with [%d] inside", err );
- }
- // Destroy tag list
- aTagList->Reset();
- delete aTagList;
- aTagList = 0;
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoRemoveNamesCallDeleteTag
-// Sends the DeleteTag() calls to lower layers when removing names.
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoRemoveNamesCallDeleteTag()
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoRemoveNamesCallDeleteTag. iDeleteTagListArray->Count() [%d] Setting iDeleteCallbackCounter = 0",
- iDeleteTagListArray->Count() );
-
- if( iDeleteTagListArray->Count() > 0 )
- {
-
- iDeleteCallbackCounter = 0;
-
- for ( TInt k( 0 ); k < iDeleteTagListArray->Count(); k++ )
- {
- TInt ret =
- iTagManager->DeleteTag( this, (*iDeleteTagListArray)[k] );
-
- if ( ret != KErrNone )
- {
- TRAPD( err, DoHandleEventFailedL(); );
- if( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DoRemoveNamesCallDeleteTag Error handling Left with [%d]", err );
- }
- return; /** @todo reengineer into single return path */
- }
- }
- } // if there are tags to delete
- else
- {
- // if there were no tags to delete (attempt to delete non-existing tags)
- // simulating callback from successful deletion of.. 0 tags
- //iDeleteCallbackCounter = -1;
- //DeleteTagCompleted();
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesCallDeleteTag Here!" );
- }
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoRemoveNamesAfterDeleteTagCompleted
-// DeleteTag() callback calls this funciton. It counts
-// the number of callbacks, and when all callbacks have arrived,
-// goes to the next phase.
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoRemoveNamesAfterDeleteTagCompleted()
- {
- iDeleteCallbackCounter++;
-
- RUBY_DEBUG2( "CNssContactHandlerImplementation::DoRemoveNamesAfterDeleteTagCompleted. iDeleteCallbackCounter [%d], Count() [%d]", iDeleteCallbackCounter, iDeleteTagListArray->Count() );
-
- if ( iDeleteCallbackCounter == iDeleteTagListArray->Count() )
- {
- if( iNormalChangesError == KErrNone )
- {
- TRAPD( err, RemovingNamesCompletedL() );
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DoRemoveNamesAfterDeleteTagCompleted. Error [%d] in RemovingNamesCompletedL", err );
- }
- }
- else
- {
- // There is not much we can do about the deletion error
- // Retrying deletion can cause endless cycle
- // Sometimes failed deletions are ok (if we tried to delete non-existing tag)
- /** @todo reengineer SpeechItemTrainer (and/or SRS plugin) to report deletion
- of non-existing tag as success. After all they are not in the DB */
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoRemoveNamesAfterDeleteTagCompleted Deletion failed. Still simulating a successful one" );
- TRAPD( err, RemovingNamesCompletedL() );
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DoRemoveNamesAfterDeleteTagCompleted. Error [%d] in RemovingNamesCompletedL", err );
- }
- } // if (iNormalChangesError == KErrNone) else
- } // if count
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::RemovingNamesCompletedL
-// Cleans up after some names have been removed
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::RemovingNamesCompletedL()
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::RemovingNamesCompletedL" );
- iDelList.Close();
-
- if ( iDeleteTagListArray )
- {
- iDeleteTagListArray->ResetAndDestroy();
- iDeleteCallbackCounter = 0;
- }
-
- DoAddNamesL();
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoAddNamesL
-// Starts name addition sequence by fetching contacts data and ordering
-// voice tags training
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoAddNamesL()
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::DoAddNamesL" );
- TInt k( 0 );
-
- if ( iAddList.Count() == 0 )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesL Nothing to add. Setting iState = ECHIdle. Return" );
- SetState ( ECHIdle );
- // If there are events on the list, DoAddNamesCompleted will fire them
- DoAddNamesCompletedL();
- }
- else
- {
- // Create new tags and train them.
- for ( k = 0; k < iAddList.Count(); k++ )
- {
- // 3 names may be created from one contact:
- // * Main name (firstname + lastname XOR companyname)
- // * Reversed order name (usually lastname + firstname, depends on the UI language)
- // -> only if NSSVAS_CONTACTHANDLER_FREEORDER is defined
- // * Nickname
-
- TContactData contactData;
-
- contactData.iID = iAddList[k].iContactId;
- contactData.iSyncTime.UniversalTime();
-
- // Nickname
- contactData.iTitle = NULL;
- TRAPD( err, contactData.iTitle = GetContactNicknameL( iAddList[k].iContactId ) );
-
- if ( contactData.iTitle != NULL )
- {
- CleanupStack::PushL( contactData.iTitle );
- contactData.iType = ETagTypeNickName;
- User::LeaveIfError( iContactQueue.Append( contactData ) );
- CleanupStack::Pop( contactData.iTitle );
- }
-
- // Main name ( Using GetContactTitleL() )
- contactData.iTitle = NULL;
- TBool bothFound = EFalse;
- TVasTagType tagType( ETagTypeUnknown );
- TRAP( err, contactData.iTitle = GetContactTitleL( iAddList[k].iContactId, ETrue, bothFound, tagType ) );
-
- // If all the name fields are empty, nothing
- // can be done for the tag. We're finished.
- if ( contactData.iTitle != NULL )
- {
- RUBY_DEBUG2( "CNssContactHandlerImplementation::DoAddNamesL For Contact id [%d] title is: [%S]", iAddList[k].iContactId, contactData.iTitle );
- CleanupStack::PushL( contactData.iTitle );
- contactData.iType = tagType;
- User::LeaveIfError( iContactQueue.Append( contactData ) );
- CleanupStack::Pop( contactData.iTitle );
- }
-
- #ifdef NSSVAS_CONTACTHANDLER_FREEORDER
- // Default order added previously, now adding
- // secondary order if both first and lastnames are found
- if ( bothFound )
- {
- contactData.iTitle = NULL;
- TRAPD( err, contactData.iTitle = GetContactTitleL( iAddList[k].iContactId, EFalse, bothFound, tagType ) );
- if ( contactData.iTitle != NULL )
- {
- CleanupStack::PushL( contactData.iTitle );
- contactData.iType = tagType;
- User::LeaveIfError( iContactQueue.Append( contactData ) );
- CleanupStack::Pop( contactData.iTitle );
- }
- }
- #endif // NSSVAS_CONTACTHANDLER_FREEORDER
-
- }
-
- // No tag had any text.
- if ( iContactQueue.Count() == 0 )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesL. No tag had any text, return" );
- DoAddNamesCompletedL();
- }
- else
- {
- // At least some tag has some text
- RUBY_ASSERT_DEBUG( iTagArray.Count() == 0, User::Panic( KFile, __LINE__ ) );
-
- for ( k = 0; k < iContactQueue.Count(); k++ )
- {
- // (1) Create a new tag
- if ( iNewTag != NULL )
- {
- // If previous call to this function leaves, iNewTag can
- // be not deleted
- delete iNewTag;
- iNewTag = NULL;
- }
- iNewTag = iTagManager->CreateTagL( iContext );
-
- MNssRRD* rrd = iNewTag->RRD();
- MNssSpeechItem* speechItem = iNewTag->SpeechItem();
-
- // (2) Fill RRD. RRD contains client-chosen data about the tag.
- // In case of name dialing, RRD contains the contact ID,
- // which is used later to get the phone number.
- CArrayFixFlat<TInt> *id = new (ELeave) CArrayFixFlat<TInt>( 1 );
-
- CleanupStack::PushL( id );
-
- id->AppendL( iContactQueue[k].iID ); // ID
- // select a number field for voice tag
- // TInt fieldIndex( 0 );
-
- WaitUntilNoSyncBackupIsRunning();
- TRAPD( err, ReadContactL( iContactQueue[k].iID ); );
- if ( err == KErrNone )
- {
- // 1. Default voice call number set by the user
- TInt found = KErrNotFound;
- TRAP( found, iPbkHandler->FindDefaultContactFieldL( EDefaultCommand ) );
-
- if ( found == KErrNotFound )
- {
- for( TInt i = 0; i < KTaggableFieldsCount; i++)
- {
- TRAP( found, iPbkHandler->FindFieldL( KTaggableFields[i] ) );
- if( found == KErrNone && ( !iPbkHandler->IsFieldEmptyL() ) )
- {
- break; // found field
- }
- else
- {
- // When field->IsEmptyOrAllSpaces(), it is the same for us as no field present
- found = KErrNotFound;
- }
- } // for i < KTaggableFieldsCount
- }
-
- if ( found == KErrNone ) // found and is not empty
- {
- id->AppendL( iPbkHandler->FieldIdL() ); // field ID to array
- id->AppendL( EDial );
- id->AppendL( iContactQueue[k].iType );
- id->AppendL( EDefaultCommand );
- rrd->SetIntArrayL ( id );
-
- // (3) Set the training text.
- speechItem = iNewTag->SpeechItem();
- speechItem->SetTextL( *iContactQueue[k].iTitle );
-
- User::LeaveIfError( iTagArray.Append( iNewTag ) );
- // Leave protection for iNewTag completed
- // Ownership and deletion responsibility moved
- // to iTagArray
- iNewTag = NULL;
- }
- else
- {
- // field not found or is empty
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesL Did NOT identify a suitable voice dial field for contact id [%d]", iContactQueue[k].iID);
-
-
- delete iNewTag;
- iNewTag = NULL;
- } // if field else
-#ifdef __SIND_EXTENSIONS
-
- // this part creates separate voice tags for extensions
- for ( TInt i(0); i < iExtensionList.Count(); i++ )
- {
- found = KErrNotFound;
- TVasExtensionAction action = iExtensionList[i].iAction;
- TPbkFieldId fieldId = iExtensionList[i].iId;
-
- // default message number
- // default video
- // default e-mail
- // default VOIP
- if ( action == ENewMessage ||
- iExtensionList[i].iId == EPbkFieldIdPhoneNumberVideo ||
- iExtensionList[i].iId == EPbkFieldIdEmailAddress ||
- iExtensionList[i].iId == EPbkFieldIdVOIP )
- {
- // @todo Should use DefaultMessageField or something similar!!
- TRAP( found,
- iPbkHandler->FindDefaultContactFieldL( iExtensionList[i].iCommand ) );
- }
-
- /*if ( extensionField == NULL )
- {
- extensionField = item->FindField( iExtensionList[i].iId );
- }
-
- if ( extensionField == NULL && field != NULL
- && ( action == ENewMessage ) )
- {
- // if default neither default field or mobile field was not found
- // message use normal SIND field
- extensionField = field;
- fieldId = field->FieldInfo().FieldId();
- }*/
-
- // If field was not found, try to find it based on the priority lists
- if ( found == KErrNotFound )
- {
- found = FindExtensionField( action, iExtensionList[i].iId );
- // If field was found, check the field ID
- if ( found == KErrNone )
- {
- fieldId = iPbkHandler->FieldIdL();
- }
- }
-
- if ( found == KErrNone )
- {
- // create new tag
- iNewTag = iTagManager->CreateTagL( iContext );
-
- rrd = iNewTag->RRD();
- speechItem = iNewTag->SpeechItem();
-
- // set RRD data
- CArrayFixFlat<TInt> *extIds = new (ELeave) CArrayFixFlat<TInt>( 1 );
- CleanupStack::PushL( extIds );
-
- extIds->AppendL( iContactQueue[k].iID );
- extIds->AppendL( fieldId );
- extIds->AppendL( action );
- extIds->AppendL( iContactQueue[k].iType );
- extIds->AppendL( iExtensionList[i].iCommand );
-
- rrd->SetIntArrayL ( extIds );
-
- // set the training text.
- TPtr namePtr( iContactQueue[k].iTitle->Des() );
- TPtr extensionPtr( iExtensionList[i].iText->Des() );
- HBufC* tempTitle = HBufC::NewLC( namePtr.Length() + extensionPtr.Length() + KTrainingIndexSize );
- TPtr titlePtr( tempTitle->Des() );
-
- //not work: titlePtr.AppendFormat( extensionPtr, namePtr );
-
- titlePtr = extensionPtr;
- AppendExtensionMarker( titlePtr );
- TInt index = titlePtr.Find( KExtensionFormatString );
- if ( index >= 0 )
- {
- // replace %U with name
- titlePtr.Delete( index, 2 ); // delete %U
- titlePtr.Insert( index, namePtr );
- }
- speechItem->SetTextL( titlePtr );
-
- User::LeaveIfError( iTagArray.Append( iNewTag ) );
- iNewTag = NULL; //ownership changed
- CleanupStack::PopAndDestroy( tempTitle );
- CleanupStack::PopAndDestroy( extIds );
- }
- }
-
-#endif // __SIND_EXTENSIONS
- // delete id
- CleanupStack::PopAndDestroy( id );
- }
- else
- {
- // Opening contact failed. E.g. if it was just deleted by user
- RUBY_DEBUG2( "CNssContactHandlerImplementation::DoAddNamesL Failed to open contact id [%d]. Leave [%d]", iContactQueue[k].iID, err);
- CleanupStack::PopAndDestroy( id );
- delete iNewTag;
- iNewTag = NULL;
- /** @todo Try reengineering duplicated cleanups into single piece
- of the code */
- }
- } // for k .. iContactQueue
-
- if ( iTagArray.Count() == 0 )
- {
- // If there are events on the list, DoAddNamesCompleted will fire them
- DoAddNamesCompletedL();
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesL. Returned from DoAddNamesCompleted. Setting iState = ECHIdle" );
- SetState ( ECHIdle );
- }
- else
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesL Before training tags. TagCount = [%d]",
- iTagArray.Count() );
-
- iTrainCallbackCounter = 0;
- for ( k = 0; k < iTagArray.Count(); k++ )
- {
- MNssSpeechItem* speechItem = iTagArray[k]->SpeechItem();
-
- MNssSpeechItem::TNssSpeechItemResult trainRet
- = speechItem->TrainTextL( this, iTrainingParams );
-
- if ( trainRet != MNssSpeechItem::EVasErrorNone )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesL : TrainTextL call failed." );
- // Not much we can do except for timed retry.
- // This stops the contact handler.
- DoHandleEventFailedL();
- break; // no processing anymore. Quit function
- }
- } // for k < iTagArray.Count()
- } // if iTagArrayCount != 0
- }
- } // if ( iAddList.Count() != 0 )
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoAddNamesTrainingFinished
-// Called after training of a current pack of tags has finished.
-// Starts saving tags.
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoAddNamesTrainingFinished()
- {
- iSaveCallbackCounter = 0;
- iRetry = 0; // retry, if save tag fails
- iNormalChangesError = 0; // to record failures in save tag
-
- DoAddNamesSaveTag();
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoAddNamesSaveTag
-// This function has two branches:
-// (1) Initiate saving tags
-// (1) After all tags have been saved, go to the next phase.
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoAddNamesSaveTag()
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesSaveTag" );
- TInt retCode;
-
- // If all tags have been saved, go to the next phase.
- if ( iSaveCallbackCounter == iTagArray.Count() )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesSaveTag All tags have been saved, go to the next phase" );
- // Tags saved - go to the next phase
- if ( iNormalChangesError == KErrNone )
- {
- // This function is called once per 100 contacts -> It is ok to use TRAP
- TRAPD( error, DoAddNamesCompletedL() );
- if( error != KErrNone )
- {
- /** @todo Test this branch */
- // Some fatal error occured
- RUBY_ERROR1( "DoAddNamesSaveTag DoAddNamesCompletedL failed with [%d]. Disabling SIND",
- error );
- DisableEventHandling();
- }
- }
- else
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesSaveTag Saving tags failed. Try again a few times" );
- // Saving tags failed. Try again a few times, and if it still
- // doesn't work, go to fatal error handler.
- if ( iRetry < KVASCHMaxRetry )
- {
- iRetry++;
- RUBY_DEBUG2( "CNssContactHandlerImplementation::DoAddNamesSaveTag Retried saving [%d] times. [%d] retries left",
- iRetry, KVASCHMaxRetry - iRetry);
- iSaveCallbackCounter = 0;
- iNormalChangesError = KErrNone;
-
- DoAddNamesSaveTag();
- }
- else
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesSaveTag Retried saving [%d] times. Still saving fails. Handling error", iRetry );
- NormalChangesHandleError();
- }
- }
- } // if ( iSaveCallbackCounter == iTagArray.Count() )
-
- // If this is the first call to this function,
- // make "save tag" calls. After that, wait for the callbacks.
- else if ( iSaveCallbackCounter == 0 )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesSaveTag iSaveCallbackCounter == 0. Run SaveTag for [%d] contacts",
- iTagArray.Count());
- for ( TInt k( 0 ); k < iTagArray.Count(); k++ )
- {
- retCode = iTagManager->SaveTag( this, iTagArray[k] );
-
- if ( retCode != KErrNone )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesSaveTag - SaveTag failed." );
- TRAPD( err, DoHandleEventFailedL(); );
- if( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DoAddNamesSaveTag handling error Left with [%d]", err );
- }
- return;
- } // if retCode
- } // for iTagArray
- } // else if iSaveCallbackCounter == 0
- else
- {
- // iSaveCallbackCounter != 0, but different from iTagArray.Count()
- // This means, that SaveTag callbacks are still coming. We will wait for them
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesSaveTag. iSaveCallbackCounter != 0, but different from iTagArray.Count()" );
- }
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoAddNamesSaveTagCompleted
-// Saving single tag has completed.
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoAddNamesSaveTagCompleted( TInt aError )
- {
- iSaveCallbackCounter++;
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesSaveTagCompleted iSaveCallbackCounter became [%d]",
- iSaveCallbackCounter);
- // |= to let single KErrGeneral fail any number of KErrNone
- iNormalChangesError |= aError;
-
- // Check if all tags have been saved.
- DoAddNamesSaveTag();
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoAddNamesCompleted
-// When adding names has successfully finished, clean up.
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoAddNamesCompletedL()
- {
- RUBY_DEBUG2( "CNssContactHandlerImplementation::DoAddNamesCompleted. iDeleteCallbackCounter [%d], Count() [%d]", iDeleteCallbackCounter, iDeleteTagListArray->Count() );
- TInt initialDeleteTagListCount = iDeleteTagListArray->Count();
-
- iSaveCallbackCounter = 0;
- iTrainCallbackCounter = 0;
-
- // DoAddNamesCompleted if often called after voice tags have been added =>
- // Nothing has to be done at all
- TBool changedDatabase = EFalse;
-
-#ifndef __SIND_EXTENSIONS
-// Set VAS_SETS_VOICETAG on if old behaviour is needed.
-// That is, VAS sets on the voice tag field to Phonebook engine and Phonebook UI checks the contacts DB for voice tags.
-// Off means that VAS does not set voice tag field but instead Phonebook asks from VAS.
-#ifdef VAS_SETS_VOICETAG
- // add voice tag fields
- // iTagArray contains only successfully trained tags.
- // Failed items are removed.
- for ( TInt i( 0 ); i < iTagArray.Count(); i++ )
- {
- MNssRRD* rrd = iTagArray[i]->RRD();
- CArrayFixFlat<TInt>* intArray = rrd->IntArray();
- RUBY_ASSERT_DEBUG( intArray->Count() >= 2, User::Panic( KFile, __LINE__ ) );
- if ( intArray->Count() >= 2 )
- {
- TBool committed( EFalse ); // ETrue if contact is committed already
- TInt contactId( intArray->At( 0 ) );
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesCompleted. Working on contact id [%d]",
- contactId);
- TInt fieldId( intArray->At( 1 ) );
-
- WaitUntilNoSyncBackupIsRunning();
- // Open contact item based on id
- TRAPD( errFor,
- OpenContactL( contactId );
-
- RUBY_DEBUG1( "DoAddNamesCompleted Opened contact [%d]", contactId );
- TInt found == KErrNotFound;
- TRAP( found, iPbkHandler->FindDefaultContactFieldL( EDefaultCommand ) );
- if ( found == KErrNotFound )
- {
- TRAP( found, iPbkHandler->FindFieldL( fieldId ) );
- }
- // field - field, that SHOULD have voice tag attached
-
- if ( found == KErrNone )
- {
- TRAP( error, iPbkHandler->ChangeVoiceTagFieldL( ETrue ) );
- if ( error == KErrNone )
- {
- RUBY_DEBUG1("DoAddNamesCompleted Successfully added icon to the contact [%d]",
- contactId);
- iPbkHandler->CloseContactL( ETrue );
- RUBY_DEBUG1("DoAddNamesCompleted Successfully committed contact [%d]",
- contactId);
- iVoiceTagAddedList.Append( contactId );
- changedDatabase = ETrue;
- committed = ETrue;
- }
- }
- else
- {
- // field not found anymore
- RUBY_DEBUG2("DoAddNamesCompleted Field [%d] not found in (already deleted from?) contact [%d]",
- fieldId, contactId );
- iDeleteTagListArray->AppendL( NULL ); // One DeleteTag will generate one callback
- iTagManager->DeleteTag( this, iTagArray[i] );
- }
- if ( !committed )
- {
- RUBY_DEBUG1("DoAddNamesCompleted Did not change contact [%d]. Closing without committing",
- contactId);
- iPbkHandler->CloseContactL( EFalse );
- }
- ); // TRAPD errFor
- if ( errFor != KErrNone )
- {
- RUBY_DEBUG2("CNssContactHandlerImplementation::DoAddNamesCompleted Failed to add icon for contact [%d]. Error [%d]",
- contactId, errFor);
- // voice tag was not in the contacts database, delete it from VAS
- // One DeleteTag will generate one callback
- iDeleteTagListArray->AppendL( NULL );
- iTagManager->DeleteTag( this, iTagArray[i] );
- }
- } // if intArray->Count() >= 2
- } // for iTagArray
-#endif // VAS_SETS_VOICETAG
-#endif //__SIND_EXTENSIONS
-
- iTagArray.ResetAndDestroy();
-
- iAddList.Close();
-
-#ifndef __SIND_EXTENSIONS
-#ifdef VAS_SETS_VOICETAG
- // Remove voice tag icons for contacts, that failed to be trained or saved
- for( TInt l = 0 ; l < iRemoveIconList.Count(); l++ )
- {
- WaitUntilNoSyncBackupIsRunning();
- TRAPD( error, OpenContactL( iRemoveIconList[l] ) );
- if ( error != KErrNone )
- {
- RUBY_DEBUG2( "CNssContactHandlerImplementation::DoAddNamesCompleted Failed to open contact [%d]. Error [%d]", iRemoveIconList[l], error);
- }
- else
- {
- TRAP( error, iPbkHandler->ChangeVoiceTagFieldL( EFalse ) );
- if ( error == KErrNotFound )
- {
- // Nothing to remove. Already no voice tag icon
- TRAP( error, iPbkHandler->CloseContactL( EFalse ) );
- if ( error != KErrNone )
- {
- RUBY_ERROR2( "CNssContactHandlerImplementation::DoAddNamesCompleted Failed to close contact [%d]. Error [%d]", iRemoveIconList[l], error);
- }
- }
- else if ( error != KErrNone )
- {
- RUBY_ERROR2( "CNssContactHandlerImplementation::DoAddNamesCompleted Failed to remove voice tag icon for contact [%d]. Error [%d]", iRemoveIconList[l], error);
- TRAP( error, iPbkHandler->CloseContactL( EFalse ) );
- if ( error != KErrNone )
- {
- RUBY_ERROR2( "CNssContactHandlerImplementation::DoAddNamesCompleted Failed to close contact [%d]. Error [%d]", iRemoveIconList[l], error);
- }
- }
- else
- {
- iVoiceTagAddedList.Append( iRemoveIconList[l] );
- TRAP( error, iPbkHandler->CloseContactL( ETrue ) );
- if ( error != KErrNone )
- {
- RUBY_ERROR2( "CNssContactHandlerImplementation::DoAddNamesCompleted Failed to commit contact [%d]. Error [%d]", iRemoveIconList[l], error);
- }
- }
-
- } // if opened contact successfully
-
- }
-#endif // VAS_SETS_VOICETAG
-#endif //__SIND_EXTENSIONS
-
- iRemoveIconList.Close();
-
- for( TInt k( 0 ); k < iContactQueue.Count(); k++ )
- {
- delete iContactQueue[k].iTitle;
- iContactQueue[k].iTitle = NULL;
- }
- iContactQueue.Close();
-
- if( changedDatabase )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesCompleted changed DBx" );
- WaitUntilNoSyncBackupIsRunning();
- TRAPD(err, iPbkHandler->CompressL() );
- if ( err )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesCompleted Contacts DB compression failed. Error [%d]",
- err);
- }
- }
- else
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesCompleted did NOT change DB" );
- }
-
- // full resyncs are always tag additions
- if( initialDeleteTagListCount == iDeleteTagListArray->Count() )
- {
- SetState( ECHIdle );
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesCompleted Syncing with phonebook generated NO deletions" );
- // then full resync will not be initiated
- iConsecutiveErrorFullResync = 0;
- if ( iEventArray.Count() > 0 )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesCompleted There are still [%d] events in the queue. Call DoHandleEvents for them",
- iEventArray.Count() );
- TRAPD( err, DoHandleEventsL() );
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DoAddNamesCompleted. Error [%d] in DoHandleEventsL", err );
- }
- }
- else
- {
- // No self-generated events, and no pending events to handle
- // This is the only place in the code, where everything is completed
- // and nothing is pending
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesCompleted All the updates completed. No DB event is pending" );
-
- }
- }
- else
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoAddNamesCompleted Generated [%d] deletions. Starting to wait for callbacks",
- iDeleteTagListArray->Count() - initialDeleteTagListCount);
- }
-
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoAddNamesCompleted completed" );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::NormalChangesHandleError
-// Handle errors which happend when updating normal changes
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::NormalChangesHandleError()
- {
- // We can't know, what went wrong.
- // Stop contact handler, so that the next time the phone is booted
- // full synchronization happens.
- RUBY_DEBUG0( "CNssContactHandlerImplementation::NormalChangesHandleError " );
- TRAPD( err, DoHandleEventFailedL(); );
- if( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::NormalChangesHandleError DoHandleEventFailedL Left with [%d]", err );
- }
- }
-
-//---------------------------------------------------------
-// CNssContactHandlerImplementation::HandleTrainComplete
-// Saves the tag after successful training.
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::HandleTrainComplete( TInt aErrorCode )
- {
- if( aErrorCode == KErrNone )
- {
- RUBY_DEBUG1( "Training OK for %d:th name.", iTrainCallbackCounter );
-
- RUBY_DEBUG1( "CNssContactHandlerImplementation::HandleTrainComplete. iState [%d]", iState);
- RUBY_ASSERT_DEBUG( iState == ECHInitializing ||
- iState == ECHHandlingNormalChanges,
- User::Panic( KFile, __LINE__ ) );
-
- iTrainCallbackCounter++;
-
- if ( iTrainCallbackCounter == iTagArray.Count() )
- {
- if ( iState != ECHInitializing )
- {
- // assert at the beginning of the function guarantees,
- // that iState == ECHHandlingNormalChanges
- DoAddNamesTrainingFinished();
- }
- }
- }
-
- else // aErrorCode != KErrNone
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::HandleTrainComplete. Training failed for %d:th name.\n",
- iTrainCallbackCounter );
-
- RUBY_ASSERT_DEBUG( iState == ECHInitializing ||
- iState == ECHHandlingNormalChanges,
- User::Panic( KFile, __LINE__ ) );
-
- // Order removal of voice tag icon if present
- MNssRRD* rrd = iTagArray[iTrainCallbackCounter]->RRD();
- CArrayFixFlat<TInt>* intArray = rrd->IntArray();
- RUBY_ASSERT_DEBUG( intArray->Count() >= 2, User::Panic( KFile, __LINE__ ) );
- if ( intArray->Count() >= 2 )
- {
- TInt error = iRemoveIconList.Append( intArray->At(0) );
- if( error != KErrNone )
- {
- RUBY_ERROR2( "CNssContactHandlerImplementation::HandleTrainError Failed to insert [%d] into iRemoveIconList. Error [%d]",
- intArray->At(0), error);
- }
- }
- else
- {
- RUBY_ERROR2( "CNssContactHandlerImplementation::HandleTrainComplete rrd->IntArray()->Count [%d] for iTrainCallbackCounter [%d]",
- intArray->Count(), iTrainCallbackCounter);
- }
-
-
- delete iTagArray[ iTrainCallbackCounter ];
- iTagArray.Remove( iTrainCallbackCounter );
-
- if ( iTrainCallbackCounter == iTagArray.Count() )
- {
- if ( iState == ECHHandlingNormalChanges )
- {
- DoAddNamesTrainingFinished();
- }
- else
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::HandleTrainComplete Unexpected state [%d]", iState);
- }
- }
- }
- }
-
-//---------------------------------------------------------
-// CNssContactHandlerImplementation::HandleTrainError
-// Handles single tag training failure
-//---------------------------------------------------------
-//
-/*void CNssContactHandlerImplementation::HandleTrainError( enum MNssTrainTextEventHandler::TNssTrainResult )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::HandleTrainError Training failed for %d:th name.\n",
- iTrainCallbackCounter );
-
- RUBY_ASSERT_DEBUG( iState == ECHInitializing ||
- iState == ECHHandlingNormalChanges,
- User::Panic( KFile, __LINE__ ) );
-
- // Order removal of voice tag icon if present
- MNssRRD* rrd = iTagArray[iTrainCallbackCounter]->RRD();
- CArrayFixFlat<TInt>* intArray = rrd->IntArray();
- RUBY_ASSERT_DEBUG( intArray->Count() >= 2, User::Panic( KFile, __LINE__ ) );
- if ( intArray->Count() >= 2 )
- {
- TInt error = iRemoveIconList.Append( intArray->At(0) );
- if( error != KErrNone )
- {
- RUBY_ERROR2( "CNssContactHandlerImplementation::HandleTrainError Failed to insert [%d] into iRemoveIconList. Error [%d]",
- intArray->At(0), error);
- }
- }
- else
- {
- RUBY_ERROR2( "CNssContactHandlerImplementation::HandleTrainError rrd->IntArray()->Count [%d] for iTrainCallbackCounter [%d]",
- intArray->Count(), iTrainCallbackCounter);
- }
-
-
- delete iTagArray[ iTrainCallbackCounter ];
- iTagArray.Remove( iTrainCallbackCounter );
-
- if ( iTrainCallbackCounter == iTagArray.Count() )
- {
- if ( iState == ECHHandlingNormalChanges )
- {
- DoAddNamesTrainingFinished();
- }
- else
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::HandleTrainError Unexpected state [%d]", iState);
- }
- }
- }*/
-
-//---------------------------------------------------------
-// CNssContactHandlerImplementation::FullResyncStart
-// Starts a full synchronization
-//---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::FullResyncStart()
- {
- // If we have synchronized earlier, we must delete the old context.
- if ( iHaveWeEverSynced )
- {
- iContextManager->DeleteContext( this, iContext );
- }
- else
- {
- TRAPD( err, FullResyncCreateContextL() );
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::FullResyncStart. Error [%d] in FullResyncCreateContextL", err );
- }
- }
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::FullResyncCreateContextL
-// Full resync: Create a new context
-// (prev: Destroy old context, next:populate the context with tags)
-// ------------------------------------------------------------
-//
-void CNssContactHandlerImplementation::FullResyncCreateContextL()
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::FullResyncCreateContextL" );
- if ( iContext != 0 )
- {
- delete iContext;
- iContext = 0;
- }
-
- iContext = iContextManager->CreateContextL();
- iContext->SetNameL( KNssCHNameDialContext );
- iContext->SetGlobal( ETrue );
-
- TBuf8<KClientDataSize> clientDataBuf;
- iClientData.iLanguage = User::Language();
- iClientData.iContactSyncId = KErrNotFound;
-
- TRAPD( error, iClientData.ExternalizeL( clientDataBuf ) );
- if ( !error )
- {
- iContext->SetClientData( clientDataBuf );
- iContextManager->SaveContext( this, iContext );
- }
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::FullResyncCreateChanges
-// Create tags and send training requests to VAS.
-// VAS trains them and calls back when it's ready
-// ------------------------------------------------------------
-//
-void CNssContactHandlerImplementation::FullResyncCreateChangesL()
- {
- RUBY_DEBUG_BLOCK( "CNssContactHandlerImplementation::FullResyncCreateChangesL" );
-
- WaitUntilNoSyncBackupIsRunning();
-
- CContactIdArray* ids = iPbkHandler->ContactIdArrayLC();
-
- RUBY_DEBUG0( "CNssContactHandlerImplementation::FullResyncCreateChanges. iContactQueue.Count() == 0" );
- RUBY_ASSERT_DEBUG( iContactQueue.Count() == 0, User::Panic( KFile, __LINE__ ) );
- // Create change events for training
- for ( TInt k( 0 ); k < ids->Count(); k++ )
- {
- TPhonebookEvent event;
- event.iContactId = (*ids)[k];
- event.iType = EContactAdded;
- iEventArray.Append( event );
- }
-
- CleanupStack::PopAndDestroy( ids ); // Cleanup stack: empty
-
- // go to processing events
- SetState ( ECHIdle );
- TRAPD( err, DoHandleEventsL() );
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::FullResyncCreateChanges. Error [%d] in DoHandleEventsL", err );
- }
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::DeleteContextCompleted
-// DeleteContext callback. Deleting a context is part of
-// full synchronization.
-// ------------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DeleteContextCompleted( TInt aErrorCode )
- {
- if( aErrorCode == KErrNone )
- {
- // Go to the next phase of full synchronization
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DeleteContextCompleted. iState == ECHFullResync, iState [%d]", iState );
- RUBY_ASSERT_DEBUG( iState == ECHFullResync, User::Panic( KFile, __LINE__ ) );
- TRAPD( err, FullResyncCreateContextL() );
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DeleteContextCompleted. Error [%d] in FullResyncCreateContextL", err );
- }
- }
- else
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DeleteContextCompleted failed" );
- RUBY_ASSERT_DEBUG( iState == ECHFullResync, User::Panic( KFile, __LINE__ ) );
-
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DeleteContextCompleted - can't handle, stopping." );
- TRAPD( err, DoHandleEventFailedL(); );
- if( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DeleteContextCompleted Left with [%d]", err);
- }
- }
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::CausedByVoiceTagAddition
-// Check if the event was caused by voice tag field adding
-// ------------------------------------------------------------
-//
-TBool CNssContactHandlerImplementation::CausedByVoiceTagAddition( const TPhonebookEvent& aEvent )
- {
- TBool isVoiceTagAddedEvent (EFalse);
- if( EContactChanged == aEvent.iType )
- {
- for ( TInt i = 0; i < iVoiceTagAddedList.Count(); i++ )
- {
- if ( aEvent.iContactId == iVoiceTagAddedList[i] )
- {
- isVoiceTagAddedEvent = ETrue;
- iVoiceTagAddedList.Remove( i-- ); // "i--" because of removal
- // Continue iterations. We are not sure if voice tag for the given
- // contact could be changed twice
- }
- } // for
- } // if event type
- return isVoiceTagAddedEvent;
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::PeriodicCallback
-// Static callback required by Symbian Timer services.
-// ------------------------------------------------------------
-//
-TInt CNssContactHandlerImplementation::PeriodicCallback( TAny* pX )
- {
- ((CNssContactHandlerImplementation*)pX)->DoPeriodicCallback();
- return KErrNone; // useless for CPeriodic
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::DoPeriodicCallback
-// Periodically check if there are some events to process
-// ------------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoPeriodicCallback()
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoPeriodicCallback" );
- // Check is needed to eliminate unnesessary TRAP and 64 bit time operations
- // Note, that we are not checking for PeriodicAction(), but for iPeriodicHandleEventTimer == NULL
- // PeriodicAction() is a method for detection of start of the action,
- // while iPeriodicHandleEventTimer == NULL says if periodic action is being executed
- // right *now*
-
- if ( ( iState == ECHIdle ) && ( iEventArray.Count() > 0 ) && ( !PeriodicAction() ) )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::DoPeriodicCallback. iState is ECHIdle, there are [%d] events to handle and no periodic action in progress", iEventArray.Count());
- TRAPD( err, DoHandleEventsL());
- if ( err != KErrNone )
- {
- RUBY_ERROR1( "CNssContactHandlerImplementation::DoPeriodicCallback. Error [%d] in DoHandleEventsL", err );
- }
- } // if there are some events
- else
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::DoPeriodicCallback No events to handle" );
- }
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::PeriodicAction
-// Detects periodic action.
-// Checks if many events have been received "lately"
-// ---------------------------------------------------------
-//
-TBool CNssContactHandlerImplementation::PeriodicAction()
- {
- // index of the first recorded call
- TInt checkedIndex = iEventMomentIndex + 1;
- checkedIndex = checkedIndex < KEventMomentsSize ? checkedIndex : 0;
- TTime& checkedTime = iEventMoments[checkedIndex];
-
- // Check if the first recorded call happened "lately" = within last
- // KPeriodicActionInterval seconds
- TTime currentTime;
- currentTime.UniversalTime();
- TTimeIntervalMicroSeconds diff = currentTime.MicroSecondsFrom( checkedTime );
- TBool result = diff < iEndOfPeriodicActionInterval;
- if ( result == EFalse )
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::PeriodicAction. Periodic action completed." );
- RUBY_DEBUG2( "CNssContactHandlerImplementation::PeriodicAction. Periodic action completed. iEventMomentIndex [%d], checkedIndex [%d]", iEventMomentIndex, checkedIndex );
- RUBY_DEBUG1( "currentTime [%d]", I64INT(currentTime.Int64()));
- RUBY_DEBUG2( "CNssContactHandlerImplementation::PeriodicAction. diff [%d], iEndOfPeriodicActionInterval [%d]", I64INT(diff.Int64()), I64INT(iEndOfPeriodicActionInterval.Int64() ) );
-
- for( TInt i = 0; i < KEventMomentsSize; i++ )
- {
- RUBY_DEBUG2( "checkedIndex[%d] = [%d]", i, I64INT(iEventMoments[i].Int64() ) );
- }
-
- // Periodic action completed. Or hasn't even been started
- // Restore timeout values
- // iEndOfPeriodicActionInterval = KInitialPeriodicActionInterval;
- if ( iPeriodicHandleEventTimer != NULL )
- {
- // stop the timer, it was started, when periodic action was started
- RUBY_DEBUG0( "CNssContactHandlerImplementation::PeriodicAction Stopping the periodic action timer" );
- iPeriodicHandleEventTimer->Cancel();
- delete iPeriodicHandleEventTimer;
- iPeriodicHandleEventTimer = NULL;
- }
- }
- else
- {
- // Periodic action detected
- // start the timer if it is not running yet
- if( iPeriodicHandleEventTimer == NULL )
- {
- TRAPD( err, iPeriodicHandleEventTimer = CPeriodic::NewL( EPriorityNormal ) );
- if( err != KErrNone )
- {
- // This is a bad situation, but not the fatal one.
- // If we cannot use timer to detect end of periodic action,
- // Let's disable periodic action detection at all
- RUBY_DEBUG1( "CNssContactHandlerImplementation::PeriodicAction. PeriodicTimer creation failed. Error [%d]. Disabling periodic actions", err);
- result = EFalse;
- }
- else
- { // Timer was created successfully
- RUBY_DEBUG0( "CNssContactHandlerImplementation::PeriodicAction Starting the periodic action timer" );
- iPeriodicHandleEventTimer->Start( KPeriodicTimerInterval, KPeriodicTimerInterval, TCallBack( PeriodicCallback, this ) );
- }
- }
- }
- return result;
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::UpdatePeriodicActionVars
-// Update variables, used to detect if periodic action is happening
-// ------------------------------------------------------------
-//
-void CNssContactHandlerImplementation::UpdatePeriodicActionVars()
- {
- if ( ++iEventMomentIndex >= KEventMomentsSize )
- {
- iEventMomentIndex = 0;
- }
- iEventMoments[iEventMomentIndex].UniversalTime();
-
- // Update values used to detect end of periodic action
- TTimeIntervalMicroSeconds32 currInterval = MaximalInterval( iEventMoments, KEventMomentsSize, iEventMomentIndex );
- // 8 times. At the end of action, this would typically be no longer, than 0.5secs
- // Note, that this is the interval fo KEventMomentsSize events
- if ( ( currInterval.Int() << 3 ) >= ( KInitialPeriodicActionInterval ) )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::UpdatePeriodicActionVars. Calculated interval is too big. Reverting periodic interval to the max [%d] mcs", KInitialPeriodicActionInterval);
- iEndOfPeriodicActionInterval = KInitialPeriodicActionInterval;
- }
- else
- {
- currInterval = currInterval.Int() << 3;
- RUBY_DEBUG1( "CNssContactHandlerImplementation::UpdatePeriodicActionVars. Adjusting periodic interval to [%d] mcs", currInterval.Int() );
- iEndOfPeriodicActionInterval = currInterval.Int();
- }
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::MaximalInterval
-// Return maximal interval from the array of time moments
-// ------------------------------------------------------------
-//
-TTimeIntervalMicroSeconds32 CNssContactHandlerImplementation::MaximalInterval( const TTime aMoments[], const TInt aMomentsLength, const TInt aLastMomentIndex )
- {
- RUBY_ASSERT_DEBUG( aMomentsLength > 1, User::Panic( KFile, __LINE__ ) );
- TInt currIndex( aLastMomentIndex );
- TInt prevIndex = currIndex - 1 < 0 ? aMomentsLength - 1 : currIndex - 1;
- TTimeIntervalMicroSeconds32 result( 0 );
- TTimeIntervalMicroSeconds currInterval;
-
- for ( TInt i = 0; i < aMomentsLength - 1; i++ )
- {
- currInterval = aMoments[currIndex].MicroSecondsFrom( aMoments[prevIndex] );
- const TInt64& currIntVal = currInterval.Int64();
- TBool tooBigValue = currIntVal > KMaxTInt;
-
- // if high != 0, aMoments were filled in the incorrect way
- // but we should not bug the user about it
- if ( tooBigValue )
- {
- // this cannot be a negative value.. if moments are recorded in the correct order.
- // Then non-zero high means, that interval is too big to fit into
- // TTimeIntervalMicroSeconds32
- RUBY_DEBUG0( "CNssContactHandlerImplementation::MaximalInterval. Maximal interval is out of bounds" );
- result = TTimeIntervalMicroSeconds32( KMaxTInt );
- break;
- }
- else
- {
- // normal size value
- // casting is safe - we checked, that it fits into TInt
- TTimeIntervalMicroSeconds32 currInterval32 ( (TInt)currIntVal );
-
- if ( currInterval32 > result )
- {
- result = currInterval32;
- }
- }
- currIndex = currIndex - 1 < 0 ? aMomentsLength - 1 : currIndex - 1;
- prevIndex = currIndex - 1 < 0 ? aMomentsLength - 1 : currIndex - 1;
- } // for
- return result;
- }
-
-// ------------------------------------------------------------
-// CNssContactHandlerImplementation::SetState
-// Sets the contact handler state.
-// In debug, panics (via asserts) if state change is not legal
-// ------------------------------------------------------------
-//
-void CNssContactHandlerImplementation::SetState( TContactHandlerState aState )
- {
- RUBY_DEBUG2( "CNssContactHandlerImplementation::SetState from [%d] to [%d]", iState, aState);
- switch( aState )
- {
- case ECHFullResync:
- // no pending events
- RUBY_ASSERT_DEBUG( ( iDeleteTagListArray == NULL ) || ( iDeleteCallbackCounter == iDeleteTagListArray->Count() ), User::Panic( KFile, __LINE__ ) );
- RUBY_ASSERT_DEBUG( iSaveCallbackCounter == iTagArray.Count(), User::Panic( KFile, __LINE__ ) );
-
- // full resyncronization needed again if this full resyncronization fails
- RUBY_TRAP_IGNORE( SetFullResyncCrFlagL( ETrue ) );
- break;
- case ECHHandlingNormalChanges:
- RUBY_ASSERT_DEBUG( iState == ECHIdle, User::Panic( KFile, __LINE__ ) );
- RUBY_TRAP_IGNORE( SetFullResyncCrFlagL( ETrue ) );
- break;
- case ECHIdle:
- if ( iDeleteTagListArray != NULL )
- {
- RUBY_ASSERT_DEBUG( (iSaveCallbackCounter == iTagArray.Count() ) || ( iDeleteCallbackCounter == iDeleteTagListArray->Count() ), User::Panic( KFile, __LINE__ ) );
- }
- else
- {
- RUBY_ASSERT_DEBUG( ( iSaveCallbackCounter == iTagArray.Count() ) , User::Panic( KFile, __LINE__ ) );
- }
- if( iEventArray.Count() == 0 )
- {
- // Idle state and no pending events mean, that contact handler
- // completed its operations for now
- TInt errProp = iBusyProperty.Set( EContactsNoTraining );
- if ( errProp != KErrNone )
- {
- RUBY_ERROR1("CNssContactHandlerImplementation::ConstructL() Failed to set property. Error [%d]",
- errProp );
- // @todo Not a leaving function -> leave commented out
- //User::Leave( errProp ) ;
- }
- }
-
- // all changes done, no need for resyncronization
- RUBY_TRAP_IGNORE( SetFullResyncCrFlagL( EFalse ) );
-
- break;
- default:
- RUBY_ERROR0( "CNssContactHandlerImplementation::SetState Unexpected or unknown state" );
- RUBY_ASSERT_DEBUG( EFalse, User::Panic( KFile, __LINE__ ) );
-
- // failure, full resyncronization needed
- RUBY_TRAP_IGNORE( SetFullResyncCrFlagL( ETrue ) );
- break;
- }
- // actually switch state
- iState = aState;
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DataSyncStateChanged
-//
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DataSyncStateChanged( TBool aRunning )
- {
- if( !aRunning && ( iSyncBackupWaiter->IsStarted() ) )
- {
- RUBY_DEBUG0( "DataSyncStateChanged Sync became inactive and CH was waiting for it" );
- iSyncBackupWaiter->AsyncStop();
- }
- }
-
-// ---------------------------------------------------------
-// Is called when backup/restore status is changed and when backup/restore
-// state observation was just started
-// @param aRunning ETrue if some backup/restore action is in progress
-// EFalse otherwise
-// @param aRestoreType ETrue if the event is restore related
-// EFalse if the event is backup related
-// @see CNssChBackupObserver
-// ---------------------------------------------------------
-void CNssContactHandlerImplementation::BackupRestoreStateChanged( TBool aRestoreType,
- TBool aRunning )
- {
- RUBY_DEBUG2( "BackupRestoreStateChanged aRestoreType [%d], aRunning [%d]",
- aRestoreType, aRunning );
-
- if( aRestoreType && aRunning )
- {
- RUBY_DEBUG0( "Setting the Full Resync CR flag" );
- RUBY_TRAP_IGNORE( SetFullResyncCrFlagL( ETrue ) );
- }
-
- if( !aRunning && ( iSyncBackupWaiter->IsStarted() ) )
- {
- RUBY_DEBUG0( "BackupRestoreStateChanged b/r became inactive and CH was waiting for it" );
- iSyncBackupWaiter->AsyncStop();
- }
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::HandleNotifyInt
-//
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::HandleNotifyInt( TUint32 aId, TInt aNewValue )
- {
- RUBY_DEBUG0( "" );
-
- if ( aId == KSRSFFullResyncNeeded )
- {
- if ( aNewValue == KImmediateResync )
- {
- RUBY_DEBUG0( "Immediate full resync requested" );
-
- // Write the previous value back to the cenrep
- TRAP_IGNORE( SetFullResyncCrFlagL( iResyncAtBoot ) );
-
- // Create an event that will launch full resync
- TPhonebookEvent event;
- event.iType = ENullEvent;
- event.iContactId = 0;
-
- iEventArray.Append( event );
-
- // Start resync if nothing is ongoing
- if ( iState == ECHIdle )
- {
- TRAP_IGNORE( DoHandleEventsL() );
- }
- }
- }
- }
-
-// ---------------------------------------------------------
-// Sets the central repository full resync flag
-// ---------------------------------------------------------
-void CNssContactHandlerImplementation::SetFullResyncCrFlagL( TBool aResyncNeeded )
- {
- RUBY_DEBUG_BLOCKL("");
- User::LeaveIfError( iRepository->Set( KSRSFFullResyncNeeded, aResyncNeeded ) );
- iResyncAtBoot = aResyncNeeded;
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::WaitUntilNoSyncBackupIsRunning
-//
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::WaitUntilNoSyncBackupIsRunning()
- {
- RUBY_DEBUG0( "WaitUntilNoSyncBackupIsRunning start" );
- RUBY_ASSERT_DEBUG( !iSyncBackupWaiter->IsStarted(), User::Panic( KFile, __LINE__ ) );
-
- // Disconnection from phonebook should happen only once and only if b/r is running
- TBool disconnectedFromPb = EFalse;
-
- // Check the values until both data sync and backup/restore are not active
- while( iDataSyncWatcher->InProgress() || iBackupObserver->InProgress() )
- {
- RUBY_DEBUG2( "WaitUntilNoSyncBackupIsRunning Have to wait. data sync [%d], backup/restore [%d]",
- iDataSyncWatcher->InProgress(), iBackupObserver->InProgress() );
- if( !iSyncBackupWaiter->IsStarted() )
- {
- if( (!disconnectedFromPb) && iBackupObserver->InProgress() )
- {
- RUBY_DEBUG0( "WaitUntilNoSyncBackupIsRunning Disconnecting from phonebook" );
- DisconnectFromPhonebook();
- disconnectedFromPb = ETrue;
- }
- iSyncBackupWaiter->Start();
- }
- else
- {
- RUBY_ERROR0( "WaitUntilNoSyncBackupIsRunning Attempt to start already active iSyncBackupWaiter. Huge error!" );
- }
- }
-
- if( disconnectedFromPb )
- {
- RUBY_DEBUG0( "WaitUntilNoSyncBackupIsRunning Reconnecting to phonebook" );
- TRAP_IGNORE( ConnectToPhonebookL() );
- }
-
- RUBY_DEBUG0( "WaitUntilNoSyncBackupIsRunning end" );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::GetContactL
-//
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::GetContactL( TContactItemId aContactId, TBool aReadContact )
- {
- RUBY_DEBUG1( "CNssContactHandlerImplementation::GetContactL. contact id [%d]", aContactId );
- TInt err = KErrNone;
- // Number of attempts tries
- TInt attemptsTried( 0 );
- do
- {
- if( err == KErrInUse ) // i.e. not the first cycle iteration
- {
- RUBY_DEBUG2( "GetContactL Contact [%d] is locked. Waiting one more second. Retrial [%d]",
- aContactId, attemptsTried);
- // start periodic timer
- if( attemptsTried == 1) // i.e exactly the second cycle iteration
- {
- RUBY_DEBUG0( "GetContactL Creating periodic timer" );
- iContactWaitTimer = CPeriodic::NewL( EPriorityNormal );
- iContactWaitTimer->Start( KContactWaitInterval, KContactWaitInterval, TCallBack( ContactWaitCallback, this ) );
- }
- RUBY_DEBUG0( "GetContactL Starting the inner cycle waiting" );
- iContactWaiter->Start( );
- RUBY_DEBUG0( "GetContactL Waiting completed, trying to open contact again" );
- }
-
- TRAP( err, iPbkHandler->FindContactL( aContactId, aReadContact ) );
-
- attemptsTried++;
- // -1 means forever
- if( ( KMaxContactLockRetrials != -1 ) && ( attemptsTried >= KMaxContactLockRetrials ) )
- {
- RUBY_DEBUG1( "GetContactL Tried for [%d] times, still no success", attemptsTried );
- break;
- }
- }
- while( err == KErrInUse );
- if( iContactWaitTimer != NULL )
- {
- iContactWaitTimer->Cancel();
- delete iContactWaitTimer;
- iContactWaitTimer = NULL;
- }
- // Propagate all the leaves, BUT KErrInUse
- if( ( err != KErrInUse ) && ( err != KErrNone ) )
- {
- User::LeaveIfError( err );
- }
- if( err == KErrInUse )
- {
- RUBY_DEBUG1( "GetContactL Failed to lock contact [%d]. Disabling CH, will resync on reboot", aContactId );
- DisableEventHandling();
- User::Leave( KErrInUse );
- }
- RUBY_DEBUG0( "CNssContactHandlerImplementation::GetContactL completed" );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::ReadContactL
-//
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::ReadContactL( TContactItemId aContactId )
- {
- GetContactL( aContactId, ETrue );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::OpenContactL
-//
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::OpenContactL( TContactItemId aContactId )
- {
- GetContactL( aContactId, EFalse );
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::ContactWaitCallback
-//
-// ---------------------------------------------------------
-//
-TInt CNssContactHandlerImplementation::ContactWaitCallback( TAny* pX )
- {
- ((CNssContactHandlerImplementation*)pX)->DoContactWaitCallback();
- return KErrNone; // useless for CPeriodic
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::DoContactWaitCallback
-//
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::DoContactWaitCallback()
- {
- iContactWaiter->AsyncStop();
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::NoDiskSpace
-// Checks if there is not enough disk space to finish the
-// operation. Returns ETrue if there is no space.
-// ---------------------------------------------------------
-//
-TBool CNssContactHandlerImplementation::NoDiskSpace()
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::NoDiskSpace" );
- TBool diskSpace( EFalse );
- TRAP_IGNORE( diskSpace = SysUtil::FFSSpaceBelowCriticalLevelL( &iFSession, KIncreaseOfDatabaseSizes ) );
-
- if ( diskSpace )
- {
- RUBY_TRAP_IGNORE( SetFullResyncCrFlagL( ETrue ) );
- RUBY_DEBUG0( "CNssContactHandlerImplementation::NoDiskSpace NOT enough disk space available" );
- return ETrue;
- }
- else
- {
- RUBY_DEBUG0( "CNssContactHandlerImplementation::NoDiskSpace There is enough disk space" );
- return EFalse;
- }
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::TrimName
-// Substitutes separator characters in descriptor with
-// white spaces. Removes extra withspaces.
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::TrimName( HBufC* aBuf )
- {
- TPtr ptr = aBuf->Des();
-
- for ( TInt findIndex = 0; findIndex < aBuf->Des().Length(); findIndex++ )
- {
- if ( ptr[findIndex] == iSeparator )
- {
- ptr[findIndex] = ' ';
- }
- }
-
- ptr.TrimAll();
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::AppendName
-// Appends name to given buffer
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::AppendName( HBufC* aBuf, HBufC* aName )
- {
- if ( aName->Length() != 0 )
- {
- aBuf->Des().Append( iSeparator );
- aBuf->Des().Append( KNameTrainingIndex );
- aBuf->Des().Append( aName->Des() );
- }
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::AppendExtensionMarker
-// Appends marker for the extensions
-// Parameters should be in format "%U text message"
-// In which case output is "%U_2text message"
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::AppendExtensionMarker( TDes& aDes )
- {
- if ( aDes.Length() > 0 )
- {
- TInt insertPosition( 0 );
- if ( aDes.Find( KExtensionFormatString ) == 0 )
- {
- // Find the first space and insert marker to that position
- TInt firstSpace( 0 );
- firstSpace = aDes.Find( _L(" ") );
- if ( firstSpace == 2 ) // Next character after KExtensionFormatString
- {
- aDes.Delete( firstSpace, 1 );
- }
- insertPosition = 2;
- }
- // Insert marker
- aDes.Insert( insertPosition, KExtensionTrainingIndex );
- aDes.Insert( insertPosition, KNameSeparator );
- }
- }
-
-/**
-* Establishes the connection to the contact engine and
-* starts listening to it
-*/
-void CNssContactHandlerImplementation::ConnectToPhonebookL()
- {
- RUBY_ASSERT_DEBUG( (!iPbkHandler), User::Leave( KErrNotReady ) );
- iPbkHandler = CVasVPbkHandler::NewL();
- iPbkHandler->InitializeL();
- iPbkHandler->CreateContactObserverL( this );
- }
-
-/**
-* Clears the connection to the contact engine
-*/
-void CNssContactHandlerImplementation::DisconnectFromPhonebook()
- {
- delete iPbkHandler;
- iPbkHandler = NULL;
- }
-
-#ifdef __SIND_EXTENSIONS
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::ReadExtensionsL
-// Reads the extension resource file
-// ---------------------------------------------------------
-//
-void CNssContactHandlerImplementation::ReadExtensionsL()
- {
- // using StringLoader should be used, but there is no
- // access to CCoeEnv
-
-
- // letters for drives in search order
- const TBuf<1> KResourceDrivers = _L("z");
- _LIT( KResourceFileName, "nssvascontacthandler.rsc" );
-
- // number of extension commands in the resource file
- const TInt KExtensionCommandCount = 8;
-
- // load resources
- RResourceFile resourceFile;
- RFs fs;
- CleanupClosePushL( fs );
- TBool found( EFalse );
- User::LeaveIfError( fs.Connect() );
-
-
- TFileName name;
- TInt i( 0 );
- // use the first drive
- name.Append( KResourceDrivers[i] );
- name.Append(':');
- name.Append( KDC_RESOURCE_FILES_DIR );
- name.Append( KResourceFileName );
-
- while ( !found && i < KResourceDrivers.Length() )
- {
- name[0] = KResourceDrivers[i++];
-
- BaflUtils::NearestLanguageFile( fs, name );
-
- if ( BaflUtils::FileExists(fs, name) )
- {
- // open resource
- resourceFile.OpenL( fs, name );
- CleanupClosePushL( resourceFile );
- resourceFile.ConfirmSignatureL();
- found = ETrue;
- }
- }
-
- if ( !found )
- {
- User::Leave( KErrNotFound );
- }
-
- for ( TInt extensionIndex( 0 ); extensionIndex < KExtensionCommandCount; extensionIndex++ )
- {
- TExtension extension;
- TResourceReader reader;
- TBool extentionSupported( ETrue );
-
- switch ( extensionIndex )
- {
-
- case 0:
- reader.SetBuffer( resourceFile.AllocReadLC( R_SIND_EXTENSION_MOBILE ) );
- extension.iId = EPbkFieldIdPhoneNumberMobile;
- extension.iAction = EDial;
- extension.iCommand = EMobileCommand;
- break;
-
- case 1:
- reader.SetBuffer( resourceFile.AllocReadLC( R_SIND_EXTENSION_MESSAGE ) );
- extension.iId = EPbkFieldIdPhoneNumberMobile;
- extension.iAction = ENewMessage;
- extension.iCommand = EMessageCommand;
- break;
-
- case 2:
- reader.SetBuffer( resourceFile.AllocReadLC( R_SIND_EXTENSION_GENERAL ) );
- extension.iId = EPbkFieldIdPhoneNumberGeneral;
- extension.iAction = EDial;
- extension.iCommand = EGeneralCommand;
- break;
-
- case 3:
- reader.SetBuffer( resourceFile.AllocReadLC( R_SIND_EXTENSION_WORK ) );
- extension.iId = EPbkFieldIdPhoneNumberWork;
- extension.iAction = EDial;
- extension.iCommand = EWorkCommand;
- break;
-
- case 4:
- reader.SetBuffer( resourceFile.AllocReadLC( R_SIND_EXTENSION_HOME ) );
- extension.iId = EPbkFieldIdPhoneNumberHome;
- extension.iAction = EDial;
- extension.iCommand = EHomeCommand;
- break;
-
- case 5:
- if ( iVideoCallFeatureSupported )
- {
- reader.SetBuffer( resourceFile.AllocReadLC( R_SIND_EXTENSION_VIDEO ) );
- extension.iId = EPbkFieldIdPhoneNumberVideo;
- extension.iAction = EDial;
- extension.iCommand = EVideoCommand;
- }
- else
- {
- extentionSupported = EFalse;
- }
- break;
-
- case 6:
- reader.SetBuffer( resourceFile.AllocReadLC( R_SIND_EXTENSION_EMAIL ) );
- extension.iId =EPbkFieldIdEmailAddress ;
- extension.iAction = ENewEmail;
- extension.iCommand = EEmailCommand;
- break;
-
- case 7:
- if ( iVoIPFeatureSupported )
- {
- reader.SetBuffer( resourceFile.AllocReadLC( R_SIND_EXTENSION_VOIP ) );
- extension.iId = EPbkFieldIdVOIP;
- extension.iAction = EDial;
- extension.iCommand = EVoipCommand;
- }
- else
- {
- extentionSupported = EFalse;
- }
- break;
-
- default:
- User::Leave( KErrGeneral ); // !!! @todo: PANIC
- }
-
- if ( extentionSupported )
- {
- extension.iText = reader.ReadHBufCL();
- CleanupStack::PushL( extension.iText );
- User::LeaveIfError( iExtensionList.Append( extension ) );
- CleanupStack::Pop( extension.iText );
- CleanupStack::PopAndDestroy(); // AllocReadLC
- }
- }
-
- CleanupStack::PopAndDestroy( &resourceFile );
- CleanupStack::PopAndDestroy( &fs );
-
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::FindExtensionField
-// Finds the extension field based on priority lists
-// ---------------------------------------------------------
-//
-TInt CNssContactHandlerImplementation::FindExtensionField( TVasExtensionAction aAction,
- TPbkFieldId aDefaultFieldId )
- {
- TInt found = KErrNotFound;
-
- switch ( aDefaultFieldId )
- {
- case EPbkFieldIdPhoneNumberVideo:
- {
- // Use defaults for video extension
- found = ExtensionFieldFindLoop( KVideoExtensionFields, KVideoExtensionFieldsCount );
- break;
- }
-
- case EPbkFieldIdPhoneNumberMobile:
- {
- if ( aAction == ENewMessage )
- {
- // Use defaults for message extension
- found = ExtensionFieldFindLoop( KMessageExtensionFields, KMessageExtensionFieldsCount );
- }
- else
- {
- TRAP( found, iPbkHandler->FindFieldL( aDefaultFieldId ) );
- }
-
- break;
- }
-
- case EPbkFieldIdVOIP:
- {
- // Use defaults for VOIP extension
- found = ExtensionFieldFindLoop( KVOIPExtensionFields, KVOIPExtensionFieldsCount );
-
- break;
- }
-
- default:
- {
- TRAP( found, iPbkHandler->FindFieldL( aDefaultFieldId ) );
- break;
- }
- }
- return found;
- }
-
-// ---------------------------------------------------------
-// CNssContactHandlerImplementation::ExtensionFieldFindLoop
-// Finds the extension from the prioroty list arrays
-// ---------------------------------------------------------
-//
-TInt CNssContactHandlerImplementation::ExtensionFieldFindLoop( const TPbkFieldId* const aArray,
- TInt aCount )
- {
- TInt found = KErrNotFound;
-
- for ( TInt iCounter = 0; iCounter < aCount; iCounter++ )
- {
- TRAP( found, iPbkHandler->FindFieldL( aArray[iCounter] ) );
- if ( found == KErrNone )
- {
- break;
- }
- }
- return found;
- }
-
-#endif // __SIND_EXTENSIONS
-
-// End of File