diff -r 000000000000 -r 72b543305e3a email/imap4mtm/imapprotocolcontroller/src/cimapcompounddisconnect.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/imap4mtm/imapprotocolcontroller/src/cimapcompounddisconnect.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,242 @@ +// Copyright (c) 2006-2009 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: +// + +#include "cimapmailstore.h" +#include "cimapcompounddisconnect.h" +#include "cimapfolder.h" +#include "cimapfolderinfo.h" +#include "cimapsession.h" +#include "cimapsessionmanager.h" +#include "cimapcompoundsyncservice.h" +#include "cimaplogger.h" +#include "imappaniccodes.h" + +#include "mobilitytestmtmapi.h" + +CImapCompoundDisconnect::CImapCompoundDisconnect( CImapSyncManager& aSyncManager, + CMsvServerEntry& aServerEntry, + CImapSettings& aImapSettings, + CImapSessionManager& aSessionManager, + CImapMailStore& aImapMailStore, + const RPointerArray& aSessionList, + CImapOfflineControl& aImapOfflineControl, + TBool aDoDeletes ) + : CImapCompoundBase(aSyncManager, aServerEntry, aImapSettings ), + iSessionManager(aSessionManager), iSessionList(aSessionList), iImapMailStore(aImapMailStore),iImapOfflineControl(aImapOfflineControl), iDoDeletes(aDoDeletes) + { + } + +CImapCompoundDisconnect::~CImapCompoundDisconnect() + { + delete iCompoundSync; + } + +CImapCompoundDisconnect* CImapCompoundDisconnect::NewL( CImapSyncManager& aSyncManager, + CMsvServerEntry& aServerEntry, + CImapSettings& aImapSettings, + CImapSessionManager& aSessionManager, + CImapMailStore& aImapMailStore, + const RPointerArray& aSessionList, + CImapOfflineControl& aImapOfflineControl, + TBool aDoDeletes ) + { + CImapCompoundDisconnect* self = new ( ELeave ) CImapCompoundDisconnect( aSyncManager, + aServerEntry, + aImapSettings, + aSessionManager, + aImapMailStore, + aSessionList, + aImapOfflineControl, + aDoDeletes ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CImapCompoundDisconnect::ConstructL() + { + CActiveScheduler::Add(this); + iCompoundSync = CImapCompoundSyncService::NewL(iSyncManager, + iServerEntry, + iImapSettings, + iImapMailStore, + iImapOfflineControl, + ETrue); + } + +/** +Starts tha compound object by setting the active object active +@param aStatus +@param aSessionManager Reference to the session manager that is used to disconnect +@param aSessionList List of all connected sessions that need to be disconnected +*/ +void CImapCompoundDisconnect::StartOperation(TRequestStatus& aStatus, CImapSession& aSession) + { + iSession = &aSession; + __LOG_TEXT(iSession->LogId(), "CImapCompoundDisconnect::StartOperation()"); + if(iImapSettings.DeleteEmailsWhenDisconnecting() && iDoDeletes) + iNextStep = EInboxLateDeletes; + else + iNextStep = EDisconnect; + + Queue(aStatus); + CompleteSelf(); + } + +/** +Handles the compound operation state machine + +@return ETrue if compound operation is completed, + EFalse otherwise (will be called again, unless active) +*/ +TBool CImapCompoundDisconnect::DoRunLoopL() + { + SetCurrentStep(); + switch (iCurrentStep) + { + case EInboxLateDeletes: // asynchronous + { + MOBILITY_TEST_MTM_STATE(iImapSettings.ServiceId(), KMobilityTestMtmStateImapDisconnect1); // Sync'ing deletes + iCompoundSync->StartOperation(iStatus, *iSession); + iProgressState = TImap4GenericProgress::EDisconnecting; + iNextStep = EDisconnect; + SetActive(); + break; + } + case EDisconnect: // asynchronous + { + MOBILITY_TEST_MTM_STATE(iImapSettings.ServiceId(), KMobilityTestMtmStateImapDisconnect2); // disconnecting + iSessionManager.Disconnect( iStatus, iSessionList ); + iProgressState = TImap4GenericProgress::EDisconnecting; + iNextStep = EFinished; + SetActive(); + break; + } + + case EFinished: // finished + { + __LOG_TEXT(iSession->LogId(), "CImapCompoundDisconnect::Completing OK"); + iProgressState = TImap4GenericProgress::EDisconnected; + Complete(KErrNone); + return ETrue; + } + + default: + { + __ASSERT_DEBUG(EFalse, TImapServerPanic::ImapPanic(TImapServerPanic::EDisconnectCompoundUnexpectedState)); + // unexpected state - complete the request + iProgressState = TImap4GenericProgress::EIdle; + return ETrue; + } + } // end switch (iCurrentStep) + return EFalse; + } + +/** +May be called in case of a genuine cancel or a cancel for migrate. +Following a genuine cancel, the compound operation will be deleted. +Following a cancel for migrate, the compound operation will be resumed, +so the iNextState is updated here to ensure the operation is +correctly restarted. + +In either case, CMsgActive::DoCancel() is called to complete the +user request with KErrCancel. + +Note that if the default CMsgActive::DoComplete() is overridden, +then that must also be modified to handle either case described above. +*/ +void CImapCompoundDisconnect::DoCancel() + { + switch (iCurrentStep) + { + case EInboxLateDeletes: + { + iCompoundSync->Cancel(); + break; + } + case EDisconnect: + { + iProgressState = TImap4GenericProgress::EDisconnecting; + iSessionManager.Cancel(); + break; + } + case EFinished: + { + // self-completed or no outstanding request. + iProgressState = TImap4GenericProgress::EDisconnected; + break; + } + case ESuspendedForMigrate: + default : + { + __ASSERT_DEBUG(EFalse, TImapServerPanic::ImapPanic(TImapServerPanic::EDisconnectCompoundCancelUnexpectedState)); + iProgressState = TImap4GenericProgress::EIdle; + break; + } + } // end switch (iCurrentStep) + + // shouldn't be restarted after a migrate (in fact, should have + // just been cancelled normally), but if it is, then just cut to + // the finish on resume. + iNextStep = EFinished; + + if (!iCancelForMigrate) + { + // genuine cancel - update progress + iProgressErrorCode = KErrCancel; + } + CMsgActive::DoCancel(); + } + + +void CImapCompoundDisconnect::Progress(TImap4CompoundProgress& aCompoundProgress) + { + aCompoundProgress.iGenericProgress.iOperation = TImap4GenericProgress::EDisconnect; + aCompoundProgress.iGenericProgress.iState = iProgressState; + + // Put error into progress buffer + if( aCompoundProgress.iGenericProgress.iErrorCode == KErrNone ) + { + aCompoundProgress.iGenericProgress.iErrorCode = iProgressErrorCode; + } + } + +/** +Handles NO/BAD responses according to current step. +Negative server responses are considered fatal during disconnect. + +@return KErrGeneral +*/ +TInt CImapCompoundDisconnect::ProcessNegativeServerResponse() + { + iProgressErrorCode = iStatus.Int(); + return KErrGeneral; + } + +/** +Protocol Controller shouldn't attempt to resume a disconnect! +So this completes with KErrDisconnected. +*/ +void CImapCompoundDisconnect::ResumeOperationL(TRequestStatus& aStatus, CImapSession& aSession) + { + iSession = &aSession; + __LOG_TEXT(iSession->LogId(), "CImapCompoundDisconnect::Resuming"); + __ASSERT_DEBUG(EFalse, TImapServerPanic::ImapPanic(TImapServerPanic::EDisconnectCompoundCancelUnexpectedState)); + iStopForMigrate = EFalse; + + Queue(aStatus); + Complete(KErrDisconnected); + }