--- /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 <AlwaysOnlineStatusQueryInterface.h>
+#include <SenduiMtmUids.h>
+#include <es_sock.h>
+#include <MuiuOperationWait.h>
+#include <ImumInSettingsData.h>
+
+#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<TInt>(
+ 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<MMsvImapConnectionObserver*> 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<TInt>(
+ 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<TInt>(
+ 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<TInt>(
+ TImumDaSettings::EKeyAutoRetrievalInterval, EFalse ));
+ folderWait = interval * KAlwaysOnlineMinuteToSecondsMultiplier;
+ if ( interval == KAlwaysOnlineMaxLimit )
+ {
+ folderWait = ( folderWait.Int() - KAlwaysOnlineTwoMinutes );
+ }
+ }
+ else
+ {
+ folderWait = LoadSettingL<TInt>( 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<TInt>(
+ 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<TInt32>( TImumInSettings::EKeyDownloadBodySize, ETrue );
+ getMailInfo.iAttachmentSizeLimit =
+ LoadSettingL<TInt32>( 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