diff -r 000000000000 -r 72b543305e3a email/alwaysonlineemailplugin/src/AlwaysOnlineImapAgent.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/alwaysonlineemailplugin/src/AlwaysOnlineImapAgent.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,1397 @@ +/* +* Copyright (c) 2002 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: +* Email imap agent +* +*/ + +#include +#include +#include +#include +#include + +#include "AlwaysOnlineEmailPluginTimer.h" +#include "AlwaysOnlineEmailPluginLogging.h" +#include "AlwaysOnlineEmailLoggingTools.h" +#include "AlwaysOnlineImapAgent.h" +#include "AlwaysOnlineImap4FolderPopulate.h" + +const TInt KAlwaysOnlineMaxLimit = 30; // if inbox sync rate is less than this and we are using gprs, then connection is kept open all the time. +const TInt KAlwaysOnlineTwoMinutes = 120; +const TInt KAlwaysOnlineMinuteToSecondsMultiplier = 60; + + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent() +// ---------------------------------------------------------------------------- +CAlwaysOnlineImap4Agent::CAlwaysOnlineImap4Agent( + CMsvSession& aSession, + CClientMtmRegistry& aClientMtmRegistry, + MAlwaysOnlineStatusQueryInterface& aAlwaysOnlineManager, + CAlwaysOnlineEmailAgent& aEmailAgent ) + : + CAlwaysOnlineEmailAgentBase( + aSession, + aClientMtmRegistry, + aAlwaysOnlineManager, + aEmailAgent ), + iInboxId( 0 ), + iImap4StateFlags() + { + } + +// ---------------------------------------------------------------------------- +// NewL +// ---------------------------------------------------------------------------- +CAlwaysOnlineImap4Agent* CAlwaysOnlineImap4Agent::NewL( + CMsvSession& aSession, + CClientMtmRegistry& aClientMtmRegistry, + TMsvId aMailboxId, + MAlwaysOnlineStatusQueryInterface& aAlwaysOnlineManager, + CAlwaysOnlineEmailAgent& aEmailAgent ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::IsReconnectAfterError" ); + CAlwaysOnlineImap4Agent* self = new(ELeave)CAlwaysOnlineImap4Agent( + aSession, + aClientMtmRegistry, + aAlwaysOnlineManager, + aEmailAgent ); + CleanupStack::PushL( self ); + self->ConstructL( aMailboxId ); + CleanupStack::Pop( self ); + return self; + } + +// ---------------------------------------------------------------------------- +// ConstructL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::ConstructL( TMsvId aMailboxId ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::ConstructL" ); + CAlwaysOnlineEmailAgentBase::ConstructL( aMailboxId ); + iImap4ClientMtm = (CImap4ClientMtm*) iClientMtmRegistry.NewMtmL( + KSenduiMtmImap4Uid ); + iFolderArray = new (ELeave) CMsvEntrySelection(); + iFlags->SetFlag( EAOBFIsImap4 ); + } + +// ---------------------------------------------------------------------------- +// ~CAlwaysOnlineImap4Agent() +// ---------------------------------------------------------------------------- +CAlwaysOnlineImap4Agent::~CAlwaysOnlineImap4Agent() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::~CAlwaysOnlineImap4Agent" ); + // cancel ongoing operations + CloseServices(); + delete iFolderArray; + delete iFolderObserver; + delete iImap4ClientMtm; + } + +// ---------------------------------------------------------------------------- +// SetStayOnlineFlagL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::SetStayOnlineFlagL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::SetStayOnlineFlagL" ); + //first, check the mode we should be operating in. + TBool isCsd = EFalse; + TRAP_IGNORE( isCsd = IsBearerCSDL() ); + + TInt inboxTime = RetrievalIntervalInMinutes( LoadSettingL( + TImumDaSettings::EKeyAutoRetrievalInterval, EFalse )); + if ( inboxTime <= KAlwaysOnlineMaxLimit && !isCsd ) + { + iImap4StateFlags.SetFlag( EAlwaysOnlineImap4StayOnline ); + } + else + { + iImap4StateFlags.ClearFlag( EAlwaysOnlineImap4StayOnline ); + } + } + +// ---------------------------------------------------------------------------- +// StartL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::StartL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::StartL" ); + //once start delay op has been started we don't ever reset that id. + if ( iStartDelayOpId == KErrNotFound ) + { + //check offline & roaming statuses from AO server + TBool suspended = EFalse; + QueryAndHandleAOServerInfoL( suspended ); + + if ( suspended ) + { + //we got iState = EEmailAgentIdle from CAlwaysOnlineEmailAgentBase::Suspend + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::StartL() We have been suspended, not starting!"); + return; + } + + iState = EEmailAgentInitialised; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::StartL. Setting state: %d ",iState ); + + + TTime home; + home.HomeTime(); + + //Let's not start immediately on start. Small delay is safer + TTimeIntervalSeconds startDelay( KInitWaitSeconds ); + home += startDelay; + + StartTimerOperationL( home, iStartDelayOpId ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::StartL(). Activated startDelayWait 5sec Op Id: %d ",iStartDelayOpId ); + }//if + else + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::StartL() called, but we're allready started. No changes to state machine"); + } + } + +// ---------------------------------------------------------------------------- +// ResumeL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::ResumeL( const TBool aConnectNow ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::ResumeL" ); + CAlwaysOnlineEmailAgentBase::ResumeL( aConnectNow ); + + // just make sure that connection will not stay open + iImap4StateFlags.ClearFlag( EAlwaysOnlineImap4StayOnline ); + } + +// ---------------------------------------------------------------------------- +// CreateImap4OperationL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::CreateImap4OperationL( + TInt aFunctionId, + TBool aCompletedOperation /*= EFalse*/ ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::CreateImap4OperationL" ); + TMsvOp dummy; + CreateImap4OperationL( dummy, aFunctionId, aCompletedOperation ); + } + +// ---------------------------------------------------------------------------- +// CreateImap4OperationL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::CreateImap4OperationL( + TMsvOp& aOpId, + TInt aFunctionId, + TBool aCompletedOperation /*= EFalse*/ ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::CreateImap4OperationL" ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::CreateImap4OperationL() aFunctionId %d", aFunctionId); + + CMsvEntrySelection* selection = new(ELeave) CMsvEntrySelection; + CleanupStack::PushL( selection ); + CMsvSingleOpWatcher* watcher = CMsvSingleOpWatcher::NewL( *this ); + CleanupStack::PushL( watcher ); + CMsvOperation* op = NULL; + + if ( aCompletedOperation ) + { + op = CMsvCompletedOperation::NewL( // CSI: 35 # cleanupstack is used + iSession, iEntry->Entry().iMtm, KNullDesC8, + KMsvLocalServiceIndexEntryId, + watcher->iStatus, KErrCancel); + + aOpId = op->Id(); + + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::CreateImap4OperationL: ADDING COMPLETED OPERATION. ID: %d", aOpId ); + } + else + { + TPckg param( this ); + + selection->AppendL( iEntry->Entry().iServiceId ); + iImap4ClientMtm->SwitchCurrentEntryL( iEntry->Entry().iServiceId ); + + op = iImap4ClientMtm->InvokeAsyncFunctionL( + aFunctionId, *selection, param, watcher->iStatus); + + aOpId = op->Id(); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::CreateImap4OperationL: ADDING CONNECT OPERATION. ID: %d", aOpId ); + + } + CleanupStack::PushL( op ); + AppendWatcherAndSetOperationL( watcher, op ); // takes immediately ownership + CleanupStack::Pop( 2, watcher ); // op // CSI: 12,47 # nothing wrong + CleanupStack::PopAndDestroy( selection );//selection + } + + +// ---------------------------------------------------------------------------- +// ConnectAndUpdateHeadersL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::ConnectAndUpdateHeadersL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::ConnectAndUpdateHeadersL" ); + KAOEMAIL_LOGGER_WRITE_FORMAT( "CAlwaysOnlineImap4Agent::ConnectAndUpdateHeadersL(). Starting to connect into: %d", iEntry->Entry().Id() ); + + //Just connect. Whether to stay online or just poll, is decided elsewhere + if ( iImap4StateFlags.Flag( EAlwaysOnlineImap4StayOnline ) && !IsEmn() ) + { + KAOEMAIL_LOGGER_WRITE(" CAlwaysOnlineImap4Agent::ConnectAndUpdateHeadersL() Connecting to stay online"); + //do full sync, inbox and folders + CreateImap4OperationL( iConnectAndStayOnlineOpId, + KIMAP4MTMConnectAndSyncCompleteAfterDisconnect, + EFalse ); + iState = EEmailAgentConnectingToStayOnline; + + //folder sync is started from HandleImapConnectionEvent after sync completes + //mail partial fetch is also started from HandleImapConnectionEvent + } + else + { + KAOEMAIL_LOGGER_WRITE(" CAlwaysOnlineImap4Agent::ConnectAndUpdateHeadersL() Doing plaing connect"); + //just connect. After this completes, sync is invoked elsewhere + CreateImap4OperationL( iConnectOpId, KIMAP4MTMConnect, EFalse ); + iState = EEmailAgentPlainConnecting; + } + + + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::ConnectAndUpdateHeadersL(). Setting state: %d ",iState ); + } + +// ---------------------------------------------------------------------------- +// DisconnectL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::DisconnectL( TBool aAutomatic ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::DisconnectL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::DisconnectL"); + + TBuf8<1> dummyParams; + dummyParams.Zero(); + CMsvSingleOpWatcher* watcher = CMsvSingleOpWatcher::NewL( *this ); + CleanupStack::PushL( watcher ); + CMsvOperation* op = NULL; + + if ( iEntry->Entry().Connected() ) + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::DisconnectL() Connected"); + CMsvEntrySelection* selection = new(ELeave) CMsvEntrySelection; + CleanupStack::PushL( selection ); + selection->AppendL( iEntry->Entry().iServiceId ); + iImap4ClientMtm->SwitchCurrentEntryL( iEntry->Entry().iServiceId ); + op = iImap4ClientMtm->InvokeAsyncFunctionL( + KIMAP4MTMDisconnect, *selection, dummyParams, watcher->iStatus); + + iDisconnectOpId = op->Id(); + CleanupStack::PopAndDestroy( selection );//selection + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::DisconnectL: ADDING DISCONNECT OPERATION: %d", iDisconnectOpId ); + } + else + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::DisconnectL() Not connected"); + //already disconnected + op = CMsvCompletedOperation::NewL( + iSession, iEntry->Entry().iMtm, KNullDesC8, + KMsvLocalServiceIndexEntryId, + watcher->iStatus, KErrCancel); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::DisconnectL: ADDING COMPLETED OPERATION: %d", op->Id() ); + } + + CleanupStack::PushL( op ); + AppendWatcherAndSetOperationL( watcher, op ); // takes immediately ownership + CleanupStack::Pop( 2, watcher); // op // CSI: 12,47 # nothing wrong + + if ( aAutomatic ) + { + iState = EEmailAgentAutoDisconnecting; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::DisconnectL. Setting state: %d ",iState ); + } + else + { + iState = EEmailAgentUserDisconnecting; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::DisconnectL. Setting state: %d ",iState ); + } + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::DisconnectL"); + } + +// ---------------------------------------------------------------------------- +// SynchroniseNewL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::SynchroniseNewL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::SynchroniseNewL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::SynchroniseNewL"); + TBuf8<1> dummyParams; + dummyParams.Zero(); + + CMsvSingleOpWatcher* watcher = CMsvSingleOpWatcher::NewL(*this); + CleanupStack::PushL( watcher ); + CMsvOperation* op = NULL; + + //we must be connected to use inboxnewsync + if ( iEntry->Entry().Connected() ) + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::SynchroniseNewL() Connected"); + SetLastSuccessfulUpdate(); + CMsvEntrySelection* selection = new(ELeave) CMsvEntrySelection; + CleanupStack::PushL( selection ); + selection->AppendL( iEntry->Entry().iServiceId ); + iImap4ClientMtm->SwitchCurrentEntryL( iEntry->Entry().iServiceId ); + op = iImap4ClientMtm->InvokeAsyncFunctionL( + KIMAP4MTMFullSync, *selection, dummyParams, watcher->iStatus); + + iSyncOpId = op->Id(); + + CleanupStack::PopAndDestroy( selection );//selection + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::SynchroniseNewL: Adding synchronise new operation. ID: %d", iSyncOpId ); + + iState = EEmailAgentSynchronising; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::SynchroniseNewL. Setting state: %d ",iState ); + } + else + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::SynchroniseNewL() Not connected"); + //for some reason we have been disconnected before we got to sync part. Invoke normal retry procedure + iError = KErrDisconnected; //this error will cause us to retry + op = CMsvCompletedOperation::NewL( + iSession, iEntry->Entry().iMtm, KNullDesC8, + KMsvLocalServiceIndexEntryId, + watcher->iStatus, KErrCancel); + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::SynchroniseNewL: Connection was dropped, retry!" ); + } + + CleanupStack::PushL( op ); + AppendWatcherAndSetOperationL( watcher, op ); // takes immediately ownership + CleanupStack::Pop( 2, watcher); // op // CSI: 12,47 # nothing wrong + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::SynchroniseNewL"); + } + +// ---------------------------------------------------------------------------- +// HandleImapConnectionEvent() from MMsvImapConnectionObserver +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::HandleImapConnectionEvent( + TImapConnectionEvent aConnectionEvent ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::HandleImapConnectionEvent" ); + TInt trapErr = KErrNone; + switch ( aConnectionEvent ) + { + case ESynchronisationComplete: + //we can reset retrycounter when sync has occurred. Because it can be + //taken as success, so it would not be retrying for same connection anymore. + iRetryCounter = 0; + + //this event can be used also to set last successful update + SetLastSuccessfulUpdate(); + + if ( iImap4StateFlags.Flag( EAlwaysOnlineImap4StayOnline ) /*iStayOnline*/ ) + { + if ( iFilteredPopulateOpId == KErrNotFound ) + { + // start fetch new mail operation + TRAP( trapErr, FetchNewMailL() ); + if ( trapErr != KErrNone ) + { + // try to start folder sync timer not the folder sync itself, because + // they were synced on connect already + TRAP( trapErr, StartFolderSyncTimerL() ); + } + } + } + break; + case EDisconnecting: + break; + case EConnectionCompleted: + break; + default: + break; + } + TRAP_IGNORE( CallNewMessagesL() ); + } + + +// ---------------------------------------------------------------------------- +// ChangeNextStateL +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::ChangeNextStateL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::ChangeNextStateL" ); + AOLOG_WRMV( "start iState: ", EAoMailPluginStates, iState, EAoLogSt3 ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::ChangeNextStateL() iState: %d", iState); + + if ( iState == EEmailAgentAutoDisconnecting && + iImap4StateFlags.Flag( EAlwaysOnlineImap4RemoveMeImmediately ) ) + { + if ( !iImap4StateFlags.Flag( EAlwaysOnlineImap4DontRemoveOnDisconnect ) ) + { + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::ChangeNextStateL() RemoveMeL 0x%x", iEntry->Entry().Id() ); + RemoveMe(); + return; + } + else + { + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::ChangeNextStateL() change 0x%x back to normal", iEntry->Entry().Id() ); + iImap4StateFlags.ClearFlag( EAlwaysOnlineImap4DontRemoveOnDisconnect ); + iImap4StateFlags.ClearFlag( EAlwaysOnlineImap4TemporaryConnectionObserver ); + iImap4StateFlags.ClearFlag( EAlwaysOnlineImap4DontReconnect ); + iImap4StateFlags.ClearFlag( EAlwaysOnlineImap4StayOnline ); + iImap4StateFlags.ClearFlag( EAlwaysOnlineImap4RemoveMeImmediately ); + } + } + + + //if we are waiting for schedule to start, we don't handle conn errors. + //this should only occur if conn op has been started just before schedule ends. + if ( iError != KErrNone && iState != EEmailAgentTimerWaitingForStart ) + { + HandleOpErrorL(); + } + + switch ( iState ) + { + // Agent just constructed ( or settings changed ) and ready. Should be + // here only when settings have been saved with always online or mail + // message notifications on. + case EEmailAgentInitialised: + //settings may have been changed, reset all pending operations + //because their timings can be different compared to newly saved settings + + ResetAll(); + + if ( !IsEmn() ) + { + CheckAndHandleSchedulingL();//starts schedule timers and sets state accordingly + if ( iWaitForStopOpId != KErrNotFound || + ( iWaitForStopOpId == KErrNotFound && + iWaitForStartOpId == KErrNotFound ) )//no start or stop waiters, all times + { + //CheckAndHandleScheduling started waitForStopTimer + StartWaitTimerL(); + } + //else, do nothing, we wait until waitForStartTimer expires and starts updates again + } + else + { + iState = EEmailAgentIdle; + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::ChangeNextStateL() EMN is on --> no scheduling or timers needed!"); + } + break; + + //case EEmailAgentConnected: + case EEmailAgentConnecting: + DisconnectL( ETrue ); + break; + case EEmailAgentPlainConnecting: + SynchroniseNewL(); + break; + case EEmailAgentSynchronising: + FetchNewMailL(); //check filtering options and acts accordingly + break; + case EEmailAgentFetching: + if ( IsTemporary() || ( iImap4StateFlags.Flag( EAlwaysOnlineImap4StayOnline ) && + !IsEmn() ) ) + { + StartFolderSyncTimerL(); + } + else + { + DisconnectL( ETrue );// Folder's not synchronized when EMN is on + } + break; + case EEmailAgentConnectingToStayOnline: + //if this has completed, we have to connect again + ConnectIfAllowedL( iConnectAndStayOnlineOpId ); + break; + case EEmailAgentConnectFailed: + case EEmailAgentQueued: + case EEmailAgentReconnecting: + case EEmailAgentAutoDisconnecting: + case EEmailAgentUserDisconnecting: + case EEmailAgentConnTerminated://red key + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::ChangeNextStateL() StartWaitTimerL"); + if ( IsReconnectAfterError() ) + { + StartWaitTimerL(); + } + else + { + DisconnectL( ETrue );// Folder's not synchronized when EMN is on + // disconnect if we are connected + iState = EEmailAgentIdle; + //give up, reset retry counter + iRetryCounter = 0; + CreateCompletedOpL(); + } + break; + case EEmailAgentTimerWaiting: + // Just make sure that wait has completed before connecting + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::ChangeNextStateL() ConnectIfAllowedL"); + ConnectIfAllowedL( iIntervalWaitId ); + break; + + case EEmailAgentTimerWaitingForStart: + // Wait end, can connect + ConnectIfAllowedL( iWaitForStartOpId ); + // Else, do nothing, we are not going to change state until + // waitForStart timer completes + break; + case EEmailAgentIdle: + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::ChangeNextStateL() Idling.... zZzZzZzZzzzzzzzzzzzzz"); + // No handling for idle, we just "hang around" + break; + case EEmailAgentFatalError: + // Something is so wrong that connection cannot be made + // without user intervention like incorrect settings or such + DisplayGlobalErrorNoteL(); + SwitchAutoUpdateOffL(); + + break; + default: + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::ChangeNextStateL() Unknown state!: %d,resetting all!", iState); + ResetAll(); + iState = EEmailAgentInitialised; + CreateCompletedOpL(); + break; + } + AOLOG_WRMV( "end iState: ", EAoMailPluginStates, iState, EAoLogSt3 ); + } + +// ---------------------------------------------------------------------------- +// StartWaitTimerL +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::StartWaitTimerL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::StartWaitTimerL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::StartWaitTimerL"); + + if ( iIntervalWaitId > KErrNotFound ) + { + KAOEMAIL_LOGGER_WRITE_FORMAT("already waiting, try to find wait operation: %d", iIntervalWaitId ); + const TInt count = iOperations.Count(); + for ( TInt i = count - 1; i >= 0; i-- ) + { + CMsvOperation& oper = iOperations[i]->Operation(); + if ( oper.Id() == iIntervalWaitId ) + { + CMsvSingleOpWatcher* opWatcher = iOperations[i]; + KAOEMAIL_LOGGER_WRITE("wait operation found, delete it"); + iOperations.Delete( i ); + delete opWatcher; + iIntervalWaitId = KErrNotFound; + break; + } + } + + } + + //waiting already + if ( iState == EEmailAgentTimerWaiting ) + { + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::StartWaitTimerL, already waiting"); + return; + } + + TTime time; + time.HomeTime(); + + //if just exited settings we should connect, only when AO is on (not EMN). + if ( iFlags->Flag( EAOBFConnectNow ) && !IsEmn() ) + { + // Set to false, one time only + iFlags->ClearFlag( EAOBFConnectNow ); + TTimeIntervalSeconds conn = KInitWaitSeconds; + time += conn; + + StartTimerOperationL( time, iIntervalWaitId ); + iState = EEmailAgentTimerWaiting; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::StartWaitTimerL. Connecting in 5 seconds. Op Id: %d ",iIntervalWaitId ); + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::StartWaitTimerL"); + return; + } + + + //if we are retrying a connection. n quick retries and then qive up + if ( ( iRetryCounter % KAOMaxRetries ) != 0 ) + { + TTimeIntervalSeconds seconds( 0 ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::StartWaitTimerL() iRetryCounter %d", iRetryCounter); + + switch ( (iRetryCounter % KAOMaxRetries) ) + { + //values for these retry times configured in AlwaysOnlineEmailAgentBase.h + case 1: + case 2: // CSI: 47 # see comment above + seconds = EEMailAgentReconnectThree; + break; + default: + seconds = EEMailAgentReconnectFive; + break; + }//switch + + time += seconds; + }//if + else if ( iState == EEmailAgentQueued ) + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::StartWaitTimerL() EEmailAgentQueued"); + TTimeIntervalSeconds seconds( 0 ); + seconds = EEMailAgentReconnectFour; + time += seconds; + } + else if ( !IsEmn() ) + { + TInt minutes = RetrievalIntervalInMinutes( LoadSettingL( + TImumDaSettings::EKeyAutoRetrievalInterval, EFalse )); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::StartWaitTimerL() Minutes to wait: %d", minutes); + + TTimeIntervalMinutes intervalMinutes( minutes ); + time += intervalMinutes; + } + + StartTimerOperationL( time, iIntervalWaitId ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::StartWaitTimerL. Interval timer started. Op Id: %d ",iIntervalWaitId ); + + iState = EEmailAgentTimerWaiting; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::StartWaitTimerL. Setting state: %d ",iState ); + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::StartWaitTimerL"); + } + + + +// ---------------------------------------------------------------------------- +// FetchNewMailL +// ---------------------------------------------------------------------------- +TMsvOp CAlwaysOnlineImap4Agent::FetchNewMailL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::FetchNewMail" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::FetchNewMailL"); + // This is completed because Always Online is supposed to only synchronize the headers. + TMsvOp opId = KErrNotFound; + iState = EEmailAgentFetching; + CreateImap4OperationL( opId, 0, ETrue ); + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::FetchNewMailL"); + return opId; + } + +// ---------------------------------------------------------------------------- +// FindInboxL +// ---------------------------------------------------------------------------- +TMsvId CAlwaysOnlineImap4Agent::FindInboxL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::FindInboxL" ); + TMsvId inboxId = KErrNotFound; + TMsvEntry child; + const TInt count = iEntry->Count(); + _LIT( KInboxName, "Inbox"); + + for ( TInt loop = 0; loop < count && inboxId == KErrNotFound; loop++ ) + { + child = (*iEntry)[loop]; + if ( child.iType == KUidMsvFolderEntry && + child.iDetails.CompareF( KInboxName ) == 0 ) + { + inboxId = child.Id(); + } + } + return inboxId; + } + +// ---------------------------------------------------------------------------- +// HandleOpErrorL +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::HandleOpErrorL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::HandleOpErrorL" ); + AOLOG_WRMV("iError: ", EAoNormalError, iError, EAoLogSt3); + AOLOG_WRMV( "start iState: ", EAoMailPluginStates, iState, EAoLogSt3 ); + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpErrorL() Error Handling started" ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::HandleOpErrorL() Error ID: %d", iError ); + switch ( iError ) + { + case KErrNone: + //shouldn't come here if KErrNone + break; + case KErrAbort: + case KErrCancel: + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpErrorL(): KErrCancel"); + //sometimes we seem to get these errors with connection operations. + //so go to initialised state -> reset all + iError = KErrNone; + iState = EEmailAgentInitialised; //this will be changed where those timers were cancelled. + break; + + case KErrGeneral://seems that this is what is given when phone/csd is in use + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpErrorL(): KErrGeneral"); + iState = EEmailAgentQueued; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::HandleOpErrorL. Setting state: %d ",iState ); + break; + case KErrInUse: + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpErrorL(): KErrInUse"); + iState = EEmailAgentQueued; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::HandleOpErrorL. Setting state: %d ",iState ); + break; + //fatal errors, cannot recover without user intervention + case KErrImapServerNoSecurity: + case KErrImapTLSNegotiateFailed: + case KImskSSLTLSNegotiateFailed: + case KErrImapBadLogon: + case KErrCorrupt: + { + iState = EEmailAgentFatalError; + iRetryCounter = 0; + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::HandleOpErrorL. Fatal Error: %d.",iError ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::HandleOpErrorL. Setting state: %d ",iState ); + } + break; + + case KErrAoServerNotFound: + HandleDefaultError(); + break; + case KErrConnectionTerminated: + case KErrTimedOut: + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpErrorL. KErrConnectionTimedOut(-33) OR KErrConnectionTerminated"); + iState = EEmailAgentConnTerminated; + break; + + //just let these go to default retry mechanism + + case KErrImapServerLoginDisabled: + case KErrImapServerParse: + case KErrImapServerBusy: + case KErrImapServerVersion: + case KErrImapSendFail: + case KErrImapSelectFail: + case KErrImapWrongFolder: + case KErrImapCantDeleteFolder: + case KErrImapInvalidServerResponse: + case KImskErrorDNSNotFound: + case KImskErrorControlPanelLocked: + case KImskErrorISPOrIAPRecordNotFound: + case KImskErrorActiveSettingIsDifferent: + case KImskSecuritySettingsFailed: + case KErrImapConnectFail: + case KErrImapServerFail://how fatal is this? + case KErrDisconnected: + + default: + HandleDefaultError(); + break; + }; + //reset error + iError = KErrNone; + AOLOG_WRMV( "end iState: ", EAoMailPluginStates, iState, EAoLogSt3 ); + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpErrorL() iError Has been reset to KErrNone"); + } + +// ---------------------------------------------------------------------------- +// DoSyncDisconnectL +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::DoSyncDisconnectL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::DoSyncDisconnectL" ); + if( iEntry->Entry().Connected() ) + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::DoSyncDisconnectL() Doing SyncDisconnect! "); + + TBuf8<1> dummyParams; + dummyParams.Zero(); + // Needed to change next operation to synchronized + CMsvOperationActiveSchedulerWait* wait = + CMsvOperationActiveSchedulerWait::NewLC(); + + CMsvEntrySelection* selection = new(ELeave) CMsvEntrySelection; + CleanupStack::PushL( selection ); + + selection->AppendL( iEntry->Entry().iServiceId ); + iImap4ClientMtm->SwitchCurrentEntryL( iEntry->Entry().iServiceId ); + CMsvOperation* op = iImap4ClientMtm->InvokeAsyncFunctionL( + KIMAP4MTMDisconnect, *selection, dummyParams, wait->iStatus ); + + // Start wait object + wait->Start(); + + delete op; + CleanupStack::PopAndDestroy( 2, wait ); // selection // CSI: 12,47 # nothing wrong + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::DoSyncDisconnectL() Should be disconnected now! "); + } + } + +// ---------------------------------------------------------------------------- +// Called from OpCompleted +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::HandleOpCompleted( + TMsvOp opId, + TInt aCompletionCode ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::HandleOpCompleted" ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::HandleOpCompleted(). Completion code %d",aCompletionCode ); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::HandleOpCompleted(). opId = %d",opId ); + + TInt trapErr = KErrNone; + //save error code so we can handle errors elsewhere + if ( opId == iConnectAndStayOnlineOpId ) + { + //if this completes, reconnect. KErrDisconnected causes us to invoke retry mechanism + iError = aCompletionCode; + + if ( iDisconnectOpId == KErrNotFound ) + { + //if we ourselves disconnected, we don't want to reconnect + if ( iError == KErrNone ) + { + //if no real error, set this so we will reconnect + iError = KErrDisconnected; + } + } + else + { + iDisconnectOpId = KErrNotFound; + } + + iConnectAndStayOnlineOpId = KErrNotFound; + } + else if( ( opId == iConnectSyncOpId || + opId == iConnectOpId || + opId == iSyncOpId ) && + aCompletionCode != KErrNone ) + { + iError = aCompletionCode; + SetLastUpdateFailed(); + } + else if ( opId == iConnectSyncOpId ) + { + iError = KErrNone; + iConnectSyncOpId = KErrNotFound; + iRetryCounter = 0; //reset retry counter + } + else if ( opId == iConnectOpId ) + { + iError = KErrNone; + iConnectOpId = KErrNotFound; + iRetryCounter = 0; //reset retry counter + } + else if ( opId == iSyncOpId ) + { + iError = KErrNone; + iSyncOpId = KErrNotFound; + iRetryCounter = 0; //reset retry counter + } + else if ( opId == iIntervalWaitId ) + { + iIntervalWaitId = KErrNotFound; + } + else if ( opId == iWaitForStopOpId ) + { + if ( aCompletionCode == KErrNone ) + { + iWaitForStopOpId = KErrNotFound; + TRAP( trapErr, CheckAndHandleSchedulingL() ); + if ( trapErr != KErrNone ) + { + //can't know why leaved. just reset all and restart + ResetAll(); + iState = EEmailAgentInitialised; + } + } + } + else if ( opId == iWaitForStartOpId ) + { + if ( aCompletionCode == KErrNone ) + { + iWaitForStartOpId = KErrNotFound; + TRAP( trapErr, CheckAndHandleSchedulingL() ); + if ( trapErr != KErrNone ) + { + //can't know why leaved. just reset all and restart + ResetAll(); + iState = EEmailAgentInitialised; + } + } + } + else if ( opId == iStartDelayOpId ) + { + iFlags->SetFlag( EAOBFConnectNow ); + //leave id untouched. We need this only once, on bootup, or when agent is activated via settings + //we use this to check is it used already + } + else if ( opId == iFolderUpdateTimerOpId ) + { + //timer is restarted when BatchEnd operation completes + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpCompleted DoFolderSyncL() called, iFolderUpdateTimerOpId reseted"); + iFolderUpdateTimerOpId = KErrNotFound; + TRAP( trapErr, DoFolderSyncL() ); + if( trapErr != KErrNone ) + { + //folder sync failed for some reason. If it's timer isn't restarted + //do it now + if( iFolderUpdateTimerOpId == KErrNotFound ) + { + TRAP( trapErr, StartFolderSyncTimerL() ); + //no handling for leave. Just give up with folder sync + } + } + } + else if ( opId == iFolderSyncOpId ) + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpCompleted iFolderSyncOpId completed"); + //restart folder update timer + iFolderSyncOpId = KErrNotFound; + if ( iImap4StateFlags.Flag( + EAlwaysOnlineImap4StartFetchAfterFolderSync ) ) + { + TRAP( trapErr, FetchNewMailL() ); + iImap4StateFlags.ClearFlag( + EAlwaysOnlineImap4StartFetchAfterFolderSync ); + } + else + { + TRAP( trapErr, StartFolderSyncTimerL() ); + } + //no handling for leave. Just give up with folder sync + } + else if ( opId == iFilteredPopulateOpId ) + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::HandleOpCompleted iFilteredPopulateOpId completed"); + //restart folder update timer + iFilteredPopulateOpId = KErrNotFound; + TRAP( trapErr, StartFolderSyncTimerL() ); + //no handling for leave. Just give up with folder sync + } + + TRAP_IGNORE( CallNewMessagesL() ); + } + + +// ---------------------------------------------------------------------------- +// CreateCompletedOpL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::CreateCompletedOpL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::CreateCompletedOpL" ); + CreateImap4OperationL( 0, ETrue );//creates completed operation + } + +// ---------------------------------------------------------------------------- +// DoFolderSyncL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::DoFolderSyncL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::DoFolderSyncL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::DoFolderSyncL"); + //do folder sync using fullsync function. No point in using several separate foldersync functions because + //there is no performance benefit and it is also far more complex to implement. Also data traffic is higher + //if separate folders are synced + + if ( iEntry->Entry().Connected() ) + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::DoFolderSyncL() Connected"); + KAOEMAIL_LOGGER_WRITE_FORMAT("CAlwaysOnlineImap4Agent::DoFolderSyncL() Folder count %d", iFolderArray->Count() ); + if ( iFolderArray->Count() > 1 && + iFilteredPopulateOpId == KErrNotFound ) + { + //only if connected. We shouldn't get here if not connected, but to be sure... + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::DoFolderSyncL() Folder sync with KIMAP4MTMFullSync started"); + CreateImap4OperationL( iFolderSyncOpId, + KIMAP4MTMFullSync, EFalse ); + + // it *can* happen so that fetching of the email is still in progress while this is started, it could be handled so that + // folder sync timer is re-started in that case instead of starting full sync. + // Added iFilteredPopulateOpId == KErrNotFound because of that, maybe that is enough? + + } + else + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::DoFolderSyncL() just create compeleted operation"); + CreateImap4OperationL( iFolderSyncOpId, 0, ETrue ); + } + } + else + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::DoFolderSyncL() Connection closed, let's try to connect again!"); + iState = EEmailAgentConnectingToStayOnline; // let's try to connect again + } + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::DoFolderSyncL"); + } + + + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::StartFolderSyncTimerL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::StartFolderSyncTimerL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::StartFolderSyncTimerL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::StartFolderSyncTimerL"); + KAOEMAIL_LOGGER_WRITE_FORMAT2("iFolderUpdateTimerOpId: %d, iFilteredPopulateOpId: %d", iFolderUpdateTimerOpId, iFilteredPopulateOpId); + KAOEMAIL_LOGGER_WRITE_FORMAT("iFolderSyncOpId: %d", iFolderSyncOpId ); + if ( iImap4StateFlags.Flag( EAlwaysOnlineImap4StayOnline ) && + iFolderUpdateTimerOpId == KErrNotFound && + iFilteredPopulateOpId == KErrNotFound && + iFolderSyncOpId == KErrNotFound ) + { + TTimeIntervalSeconds folderWait; + TTime home; + home.HomeTime(); + + // If there is a temporary agent created (==EMailAoOff), which means + // user has taken connection manually. It is agreed, that in this case + // we must use value returned by CImImap4Settings::SyncRate function. + // Otherwise user would not know what interval is used for updating + // folders. + if ( LoadSettingL( + TImumDaSettings::EKeyAutoRetrieval, EFalse ) != + TImumDaSettings::EValueAutoOff ) + { + //refresh time must be less than 30 min, because we are in + // iStayOnline -mode take off 2 minutes if limit is set to 30min + // because of IMAP protocoll 29 minute timeout. 28 is safe enough + TInt interval = RetrievalIntervalInMinutes( LoadSettingL( + TImumDaSettings::EKeyAutoRetrievalInterval, EFalse )); + folderWait = interval * KAlwaysOnlineMinuteToSecondsMultiplier; + if ( interval == KAlwaysOnlineMaxLimit ) + { + folderWait = ( folderWait.Int() - KAlwaysOnlineTwoMinutes ); + } + } + else + { + folderWait = LoadSettingL( TImumInSettings::EKeySyncRate, ETrue ); + } + + // Add wait time to current time and start timer. + home += folderWait; + + KAOEMAIL_LOGGER_WRITE_DATETIME("CAlwaysOnlineImap4Agent::StartFolderSyncTimerL(): Folder timer started, will complete at: ", home ); + StartTimerOperationL( home, iFolderUpdateTimerOpId ); + }//if + + // Start inbox folder observer here... + StartFolderObserverL(); + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::StartFolderSyncTimerL"); + + } + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::AddSubscribedFoldersL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::UpdateSubscribedFoldersL( + TMsvId aFolderId ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::UpdateSubscribedFoldersL" ); + iFolderArray->Reset(); + DoUpdateSubscribedFoldersL( aFolderId ); + } + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::DoAddSubscribedFoldersL() +// NOTE: This is recursive! +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::DoUpdateSubscribedFoldersL( + TMsvId aFolderId ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::DoUpdateSubscribedFoldersL" ); + CMsvEntry* entry = iSession.GetEntryL( aFolderId ); + CleanupStack::PushL( entry ); + + const TInt count = entry->Count(); + for ( TInt loop = 0; loop < count; loop++ ) + { + TMsvEmailEntry mailEntry = (*entry)[loop]; + if ( mailEntry.iType.iUid == KUidMsvFolderEntryValue ) + { + if ( mailEntry.LocalSubscription() ) + { + iFolderArray->AppendL( mailEntry.Id() ); + } + DoUpdateSubscribedFoldersL( mailEntry.Id() ); + } + } + + CleanupStack::PopAndDestroy( entry ); + + } + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::AppendFolderArrayL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::AppendFolderArrayL( + CMsvEntrySelection& aFolders, + TMsvId aInboxId ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::AppendFolderArrayL" ); + const TInt count = iFolderArray->Count(); + TInt i = 0; + for ( i=0; i < count; i++ ) + { + if ( (*iFolderArray)[i] != aInboxId ) + { + aFolders.AppendL( (*iFolderArray)[i] ); + } + } + + } + + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::StartFolderObserverL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::StartFolderObserverL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::StartFolderObserverL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::StartFolderObserverL"); + // Start observer only if staying online + if ( iImap4StateFlags.Flag( EAlwaysOnlineImap4StayOnline ) ) + { + if ( !iFolderObserver ) + { + iFolderObserver = CAlwaysOnlineImap4FolderObserver::NewL( + iSession, + NULL, // this is set below + *this ); + } + UpdateSubscribedFoldersL( iEntry->Entry().Id() ); + iFolderObserver->ResetFoldersL( iFolderArray ); + if ( iImap4StateFlags.Flag( EAlwaysOnlineImap4DontReconnect ) ) + { + iFolderObserver->SetMailbox( iEntry->Entry().Id() ); + } + else + { + iFolderObserver->SetMailbox( 0 ); + } + iFolderObserver->Start(); + KAOEMAIL_LOGGER_WRITE("Observer started"); + } + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::StartFolderObserverL"); + } + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::StopFolderObserver() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::StopFolderObserver() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::StopFolderObserver" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::StopFolderObserver"); + if ( iFolderObserver ) + { + iFolderObserver->Stop(); + } + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::StopFolderObserver"); + } + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::HandleFolderEntryL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::HandleFolderEntryL( + const CMsvEntrySelection& aFolderArray ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::HandleFolderEntryL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::HandleFolderEntryL"); +#ifdef _DEBUG + const TInt count = aFolderArray.Count(); + for ( TInt i = 0; i < count; i++ ) + { + KAOEMAIL_LOGGER_WRITE_FORMAT( "folderId 0x%x", aFolderArray[i] ); + } +#endif + TInt index = aFolderArray.Find( iEntry->Entry().Id() ); + if ( index > KErrNotFound ) + { + // disconnected? Remove myself. + if( !iEntry->Entry().Connected() ) + { + // this is a bit dirty way. This agent is removed after disconnect is completed + KAOEMAIL_LOGGER_WRITE( "Mailbox disconnected, kill myself!"); + iImap4StateFlags.SetFlag( EAlwaysOnlineImap4RemoveMeImmediately ); + DisconnectL( ETrue ); + return; + } + } + + + // Start populate operation + // Change this so that fetch new started after folder sync, if it is going, if not, + // then just start fetch new immediately + if ( iFolderSyncOpId > KErrNotFound ) + { + StopFolderObserver(); + KAOEMAIL_LOGGER_WRITE( "Wait folder sync operation to complete"); + iImap4StateFlags.SetFlag( EAlwaysOnlineImap4StartFetchAfterFolderSync ); + } + // NOTE: Always Online is supposed to get only the headers, no need to fetch the bodies for mails + // in subscribed folders!!! + else + { + TMsvOp opId; + iState = EEmailAgentFetching; + CreateImap4OperationL( opId, 0, ETrue ); + KAOEMAIL_LOGGER_WRITE( "Compliting operation in HandleFolderEntryL"); + } + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::HandleFolderEntryL"); + } + +// --------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::FillMailOptionsL() +// --------------------------------------------------------------------------- +// +TImImap4GetPartialMailInfo CAlwaysOnlineImap4Agent::FillMailOptionsL() + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::FillMailOptionsL" ); + TImImap4GetPartialMailInfo getMailInfo; + + TInt syncFlags = LoadSettingL( + TImumInSettings::EKeySyncFlags, ETrue ); + + if ( syncFlags == TImumInSettings::EFlagDownloadHeader ) + { + getMailInfo.iGetMailBodyParts = EGetImap4EmailHeaders; + getMailInfo.iPartialMailOptions = ENoSizeLimits; + } + else + { + // Currently, other than headers can be retrieved + User::Leave( KErrNotSupported ); + } + + // Set size definitions + getMailInfo.iBodyTextSizeLimit = + LoadSettingL( TImumInSettings::EKeyDownloadBodySize, ETrue ); + getMailInfo.iAttachmentSizeLimit = + LoadSettingL( TImumInSettings::EKeyDownloadAttachmentSize, ETrue ); + getMailInfo.iTotalSizeLimit = + getMailInfo.iAttachmentSizeLimit + getMailInfo.iBodyTextSizeLimit; + getMailInfo.iMaxEmailSize = getMailInfo.iTotalSizeLimit; + + if ( getMailInfo.iMaxEmailSize == 0 ) + { + getMailInfo.iGetMailBodyParts = EGetImap4EmailHeaders; + } + getMailInfo.iDestinationFolder = KMsvNullIndexEntryId; // No destination for populate. + + return getMailInfo; + } + +// ---------------------------------------------------------------------------- +// CAlwaysOnlineImap4Agent::FetchNewMailFromSelectedFoldersL() +// ---------------------------------------------------------------------------- +TMsvOp CAlwaysOnlineImap4Agent::FetchNewMailFromSelectedFoldersL( + const CMsvEntrySelection& aFolders ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::FetchNewMailFromSelectedFoldersL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::FetchNewMailFromSelectedFoldersL"); + TMsvOp opId = 0; + + TImImap4GetPartialMailInfo getMailInfo = FillMailOptionsL(); + + KAOEMAIL_LOGGER_WRITE_FORMAT("Fetching size limit: %d", getMailInfo.iBodyTextSizeLimit); + + iState = EEmailAgentFetching; + if ( getMailInfo.iGetMailBodyParts == EGetImap4EmailHeaders ) + { + // Just complete since filtering is not in use + KAOEMAIL_LOGGER_WRITE_FORMAT("Setting is just headers, create completed operation opId = %d", opId ); + CreateImap4OperationL( opId, 0, ETrue ); + } + else + { + // read imap filtering settings + KAOEMAIL_LOGGER_WRITE_FORMAT("folder count = %d", aFolders.Count()); + + CMsvSingleOpWatcher* watcher = CMsvSingleOpWatcher::NewL(*this); + CleanupStack::PushL( watcher ); + CMsvOperation* op = CAlwaysOnlineImap4FolderPopulate::NewL( + iSession, + *iImap4ClientMtm, + iEntry->Entry().Id(), + iInboxId, + getMailInfo, + &aFolders, + watcher->iStatus ); + + CleanupStack::PushL( op ); + opId = op->Id(); + AppendWatcherAndSetOperationL( watcher, op ); // takes immediately ownership + + CleanupStack::Pop( 2, watcher); // op // CSI: 12,47 # nothing wrong + } + iFilteredPopulateOpId = opId; + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::FetchNewMailFromSelectedFoldersL"); + return opId; + } + +// ---------------------------------------------------------------------------- +// SetUpdateMailWhileConnectedL() +// ---------------------------------------------------------------------------- +void CAlwaysOnlineImap4Agent::SetUpdateMailWhileConnectedL( + TBool aAgentAlreadyCreated ) + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::SetUpdateMailWhileConnectedL" ); + KAOEMAIL_LOGGER_FN1("CAlwaysOnlineImap4Agent::SetUpdateMailWhileConnectedL"); + + if ( iImap4StateFlags.Flag( EAlwaysOnlineImap4StayOnline ) ) + { + // we are already observing... + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::SetUpdateMailWhileConnectedL ignore"); + return; + } + + if ( aAgentAlreadyCreated ) + { + iImap4StateFlags.SetFlag( EAlwaysOnlineImap4DontRemoveOnDisconnect ); + } + + iImap4StateFlags.SetFlag( EAlwaysOnlineImap4TemporaryConnectionObserver ); + iImap4StateFlags.SetFlag( EAlwaysOnlineImap4DontReconnect ); + iImap4ClientMtm->SwitchCurrentEntryL( iEntry->Entry().Id() ); + + if( iImap4ClientMtm->Entry().Entry().Connected() ) + { + iImap4StateFlags.SetFlag( EAlwaysOnlineImap4StayOnline ); + iState = EEmailAgentIdle; + StartFolderSyncTimerL(); + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::SetUpdateMailWhileConnectedL 1"); + return; + } + + // this is a bit dirty way. This agent is removed after disconnect is completed + KAOEMAIL_LOGGER_WRITE( "Mailbox disconnected even we should be connected, kill myself!"); + iImap4StateFlags.SetFlag( EAlwaysOnlineImap4RemoveMeImmediately ); + DisconnectL( ETrue ); // this creates just completed operation if service is not connected. + KAOEMAIL_LOGGER_FN2("CAlwaysOnlineImap4Agent::SetUpdateMailWhileConnectedL 2"); + } + +// ---------------------------------------------------------------------------- +// IsTemporary() +// ---------------------------------------------------------------------------- +TBool CAlwaysOnlineImap4Agent::IsTemporary() const + { + AOLOG_IN( "CAlwaysOnlineImap4Agent::IsTemporary" ); + // If temporary agent is running, then flag EAlwaysOnlineImap4TemporaryConnectionObserver + // is set. At this stage, showing of notes are not allowed, since user may get + // confused with the disk full note! + TBool result = + iImap4StateFlags.Flag( EAlwaysOnlineImap4TemporaryConnectionObserver ); + + if ( result ) + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::IsTemporary: Yes, I am temporary! No notes, plz!" ); + return ETrue; + } + else + { + KAOEMAIL_LOGGER_WRITE("CAlwaysOnlineImap4Agent::IsTemporary: No, I am not temporary! Go ahead and show notes, plz!" ); + return EFalse; + } + } + + +//EOF