ipsservices/ipssosaoplugin/src/IpsSosAOImapAgent.cpp
changeset 0 8466d47a6819
child 8 e1b6206813b4
child 18 578830873419
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipsservices/ipssosaoplugin/src/IpsSosAOImapAgent.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,550 @@
+/*
+* Copyright (c) 2008 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: 
+*     Contains imap specified sync logic
+*
+*/
+
+
+#include "emailtrace.h"
+#include <cemailaccounts.h>
+#include <imapcmds.h>
+#include <miutset.h>
+#include <impcmtm.h>
+#include <msvapi.h>
+#include <AlwaysOnlineManagerCommon.h>
+//<cmail>
+#include "CFSMailCommon.h"
+//</cmail>
+
+
+#include "IpsSosAOImapAgent.h"
+#include "IpsSosAOImapPopLogic.h"
+
+
+// from settings
+#include "ipssetdataapi.h"
+#include "ipssetutilsconsts.h"
+
+// from ipsplugin
+#include "ipsplgimap4populateop.h"
+#include "ipsplgcommon.h"
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CIpsSosAOImapAgent::CIpsSosAOImapAgent(             
+    CMsvSession& aSession,
+    MIpsSosAOAgentOperationResponse& aOpResponse,
+    TMsvId aServiceId) : CIpsSosAOBaseAgent(), 
+    iSession(aSession), iOpResponse(aOpResponse),
+    iServiceId( aServiceId ),
+    iState( EStateIdle ), iDoNotDisconnect( EFalse )
+    {
+    FUNC_LOG;
+    
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CIpsSosAOImapAgent::~CIpsSosAOImapAgent()
+    {
+    FUNC_LOG;
+    Cancel();
+    SignalSyncCompleted( iServiceId, iError );
+    ClearSignaledFlags();
+    delete iImapSettings;
+    delete iOngoingOp;
+    delete iImapClientMtm;
+    delete iMtmReg;
+    delete iDataApi;
+    iFoldersArray.Close();
+
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CIpsSosAOImapAgent* CIpsSosAOImapAgent::NewL( 
+    CMsvSession& aSession,
+    MIpsSosAOAgentOperationResponse& aOpResponse,
+    TMsvId aServiceId )
+    {
+    FUNC_LOG;
+    CIpsSosAOImapAgent* self = new (ELeave) CIpsSosAOImapAgent( 
+            aSession,  aOpResponse, aServiceId );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::ConstructL()
+    {
+    FUNC_LOG;
+    CActiveScheduler::Add(this);
+    
+    iMtmReg = CClientMtmRegistry::NewL( iSession );
+    CBaseMtm* bmtm = iMtmReg->NewMtmL( KUidMsgTypeIMAP4 );
+    iImapClientMtm = static_cast<CImap4ClientMtm*>(bmtm);
+    iDataApi = CIpsSetDataApi::NewL( iSession );
+    iState = EStateIdle; 
+    }
+ 
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::DoCancel()
+    {
+    FUNC_LOG;
+    if (iOngoingOp )
+        {
+        iOngoingOp->Cancel();
+        }
+    delete iOngoingOp;
+    iOngoingOp = NULL;
+    
+    SignalSyncCompleted( iServiceId, iError );
+    ClearSignaledFlags();
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::HandleImapConnectionEvent(
+    TImapConnectionEvent aConnectionEvent )
+    {
+    FUNC_LOG;
+    switch ( aConnectionEvent )
+        {
+        case EConnectingToServer:
+            break;
+        case ESynchronisingFolderList:
+        case ESynchronisingInbox:
+        case ESynchronisingFolders:
+            SignalSyncStarted( iServiceId );
+            break;
+        case ESynchronisationComplete:
+            break;
+        case EDisconnecting:
+            break;
+        case EConnectionCompleted:
+        default:
+            break;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::RequestResponseL( 
+        TFSProgress /*aEvent*/, 
+        TInt /*aRequestId*/ )
+    {
+    FUNC_LOG;
+    
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::RunL()
+    {
+    FUNC_LOG;
+    if ( iOngoingOp )
+        {
+        // errors are not tolerated atm
+        if (  iOngoingOp->iStatus.Int() != KErrNone )
+            {
+            iError = iOngoingOp->iStatus.Int();
+            SignalSyncCompleted( iServiceId, iError );
+            CancelAllAndDisconnectL();
+            }
+        delete iOngoingOp;
+        iOngoingOp = NULL;
+        }
+    
+    switch( iState )
+         {
+         case EStateConnectAndSync:
+             iState = EStateRefreshFolderArray;
+             SetActiveAndCompleteThis();
+             break;
+         case EStateConnectAndSyncOnHold:
+             StartSyncL();
+             break;
+         case EStateRefreshFolderArray:
+             iDataApi->GetSubscribedImapFoldersL( iServiceId , iFoldersArray );
+             iState = EStatePopulateAll;
+             SetActiveAndCompleteThis();
+             break;
+         case EStatePopulateAll:
+             PopulateAllL();
+             break;
+         case EStatePopulateOnHold:
+             PopulateAllL();
+             break;
+         case EStateFetchOngoing:
+             break;
+         case EStateFetchOnHold:
+             break;
+         case EStateDisconnect:
+             if ( !iDoNotDisconnect )
+                 {
+                 CancelAllAndDisconnectL();
+                 }
+             else
+                 {
+                 iState = EStateCompleted;
+                 SetActiveAndCompleteThis();
+                 }
+             break;
+         case EStateCompleted:
+             TRAP_IGNORE( iOpResponse.OperationCompletedL( iError ) );
+             SignalSyncCompleted( iServiceId, iError );
+             iError = KErrNone;
+             ClearSignaledFlags();
+             iState = EStateIdle;
+             break;
+         case EStateIdle:
+             break;
+         default:
+         break;
+  
+         }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TInt CIpsSosAOImapAgent::RunError( TInt aError )
+    {
+    FUNC_LOG;
+    iError = aError;
+    if ( IsConnected() && iState != EStateDisconnect )
+        {
+        TRAP_IGNORE( CancelAllAndDisconnectL() );
+        }
+    else if ( IsConnected() && iState == EStateDisconnect )
+        {
+        iSession.StopService( iServiceId );
+        iState = EStateCompleted;
+        SetActiveAndCompleteThis();
+        }
+    else
+        {
+        iState = EStateCompleted;
+        iError = KErrCancel;
+        SetActiveAndCompleteThis();
+        }
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::GetServerAddress( 
+        TBuf<KIpsSosAOTextBufferSize>& aIncomingServer ) const
+    {
+    FUNC_LOG;
+    if ( !iImapSettings )
+        {
+        return;
+        }
+    TPtrC addr = iImapSettings->ServerAddress();
+    __ASSERT_DEBUG( ( 
+            addr.Length() <= KIpsSosAOTextBufferSize ), 
+            User::Panic( KIpsSosAOPanicLit, KErrGeneral) );
+    
+    if ( addr.Length() <= KIpsSosAOTextBufferSize )
+        {
+        aIncomingServer.Copy( addr );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::GetUsername( 
+        TBuf8<KIpsSosAOTextBufferSize>& aUsername ) const
+    {
+    FUNC_LOG;
+    if ( !iImapSettings )
+        {
+        return;
+        }
+    TPtrC8 usrn = iImapSettings->LoginName();
+    __ASSERT_DEBUG( ( 
+            usrn.Length() <= KIpsSosAOTextBufferSize ), 
+            User::Panic( KIpsSosAOPanicLit, KErrGeneral) );
+    
+    if ( usrn.Length() <= KIpsSosAOTextBufferSize )
+        {
+        aUsername.Copy( usrn );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+TBool CIpsSosAOImapAgent::IsConnected() const
+    {
+    FUNC_LOG;
+    TMsvEntry tentry;
+    TMsvId service;
+    iSession.GetEntry( iServiceId, service, tentry );
+    return tentry.Connected();
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+CIpsSosAOBaseAgent::TAgentState CIpsSosAOImapAgent::GetState() const
+    {
+    FUNC_LOG;
+    return iState;
+    }
+
+// ----------------------------------------------------------------------------
+// ---------------------------------------------------------------------------- 
+void CIpsSosAOImapAgent::StartSyncL()
+    {
+    FUNC_LOG;
+    if ( iOngoingOp )
+        {
+        User::Leave( KErrNotReady );
+        }
+    LoadSettingsL( );
+    if ( !IsConnected() )
+        {
+        TPckg<MMsvImapConnectionObserver*> parameter(this);
+        // connect and synchronise starts background sync or idle
+        CMsvEntrySelection* sel = new ( ELeave ) CMsvEntrySelection();
+        CleanupStack::PushL( sel );
+        sel->AppendL( iServiceId );
+        iImapClientMtm->SwitchCurrentEntryL( iServiceId );
+        iOngoingOp = iImapClientMtm->InvokeAsyncFunctionL(
+                KIMAP4MTMConnectAndSyncCompleteAfterFullSync, 
+                *sel, parameter, iStatus);
+        CleanupStack::PopAndDestroy( sel );
+        SetActive();
+        iState = EStateConnectAndSync;
+        }
+    else
+        {
+        // do not do anything if we are connected, especially do never
+        // try to sync if sync is is already started (ex. from ips plugin)
+        // that cause problems with imap flags etc.
+        iError = KErrNone;
+        iState = EStateCompleted;
+        SetActiveAndCompleteThis();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::StartFetchMessagesL( 
+        const RArray<TMsvId>& /*aFetchMsgArray*/ )
+    {
+    FUNC_LOG;
+    
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::CancelAllAndDisconnectL()
+    {
+    FUNC_LOG;
+    iDoNotDisconnect = EFalse;
+    iState = EStateCompleted;
+    iFoldersArray.Reset();
+
+    if ( IsActive() )
+        {
+        Cancel();
+        }
+
+    if ( IsConnected() )
+        {
+        TBuf8<1> dummy;
+        CMsvEntrySelection* sel = new ( ELeave ) CMsvEntrySelection();
+        CleanupStack::PushL( sel );
+        sel->AppendL( iServiceId );
+        iImapClientMtm->SwitchCurrentEntryL( iServiceId );
+        TRAPD( error, iOngoingOp = iImapClientMtm->InvokeAsyncFunctionL(
+            KIMAP4MTMDisconnect, 
+            *sel, dummy, iStatus) );
+        CleanupStack::PopAndDestroy( sel );
+        
+        if ( error == KErrNone )
+            {
+            SetActive();
+            }
+        else
+            {
+            iSession.StopService( iServiceId );
+            SetActiveAndCompleteThis();
+            }
+        }
+    else
+        {
+        SetActiveAndCompleteThis();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::CancelAllAndDoNotDisconnect()
+    {
+    FUNC_LOG;
+    iDoNotDisconnect = ETrue;
+    if ( IsActive() )
+        {
+        Cancel();
+        }
+    iFoldersArray.Reset();
+    SignalSyncCompleted( iServiceId, KErrCancel );
+    iState = EStateCompleted;
+    SetActiveAndCompleteThis();
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::DoNotDisconnect()
+    {
+    FUNC_LOG;
+    iDoNotDisconnect = ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::ClearDoNotDisconnect()
+    {
+    FUNC_LOG;
+    iDoNotDisconnect = EFalse;
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::HoldOperations()
+    {
+    FUNC_LOG;
+    if ( IsActive() )
+        {
+        Cancel();
+        }
+    
+    if ( iState == EStatePopulateAll )
+        {
+        iState = EStatePopulateOnHold;
+        }
+    else if ( iState == EStateFetchOngoing )
+        {
+        iState = EStateFetchOnHold;
+        }
+    else if ( iState == EStateConnectAndSync )
+        {
+        iState = EStateConnectAndSyncOnHold;
+        }
+    else 
+        {
+        iState = EStateIdle;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::ContinueHoldOperations()
+    {
+    FUNC_LOG;
+    SetActiveAndCompleteThis();
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::PopulateAllL()
+    {
+    FUNC_LOG;
+    TImImap4GetPartialMailInfo info;
+    CIpsSetDataApi::ConstructImapPartialFetchInfo( info, *iImapSettings );
+    
+    if ( !IsConnected() )
+        {
+        SignalSyncCompleted( iServiceId, iError );
+        CancelAllAndDisconnectL();
+        }
+    else if ( iFoldersArray.Count() > 0 && info.iTotalSizeLimit 
+            != KIpsSetDataHeadersOnly )
+         {
+
+         // only inbox is set, do we have to populate other folders also
+         TMsvId id = iFoldersArray[0];
+         CMsvEntry* cEntry = iSession.GetEntryL( id );
+         CleanupStack::PushL( cEntry );
+         CMsvEntrySelection* sel = cEntry->ChildrenWithTypeL( 
+                 KUidMsvMessageEntry ); 
+         CleanupStack::PushL( sel );
+         
+         info.iDestinationFolder = iFoldersArray[0];
+         
+         CIpsPlgTimerOperation* dummy = NULL;
+         iImapClientMtm->SwitchCurrentEntryL( iServiceId );
+         TFSMailMsgId mbox( KIpsPlgImap4PluginUidValue, iServiceId );
+         iStatus = KRequestPending;
+         iOngoingOp = CIpsPlgImap4PopulateOp::NewL(
+                 iSession,
+                 this->iStatus,
+                 CActive::EPriorityLow,
+                 iServiceId,
+                 *dummy,
+                 info,
+                 *sel,
+                 mbox,
+                 *this,
+                 0,
+                 NULL );
+         
+         iFoldersArray.Remove( 0 );
+         SetActive();
+         iState = EStatePopulateAll;
+         CleanupStack::PopAndDestroy( 2, cEntry );
+         
+         }
+     else
+         {
+         iState = EStateDisconnect;
+         SignalSyncStarted( iServiceId );
+         SetActiveAndCompleteThis();
+         }
+    }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+void CIpsSosAOImapAgent::LoadSettingsL( )
+    {
+    FUNC_LOG;
+    delete iImapSettings;
+    iImapSettings = NULL;
+    iImapSettings = new ( ELeave ) CImImap4Settings();
+    CEmailAccounts* accounts = CEmailAccounts::NewLC();
+    TImapAccount imapAcc;
+    accounts->GetImapAccountL(iServiceId, imapAcc );
+    accounts->LoadImapSettingsL( imapAcc, *iImapSettings );
+    CleanupStack::PopAndDestroy( accounts );
+    }
+
+// ----------------------------------------------------------------------------
+// inline
+// ----------------------------------------------------------------------------    
+void CIpsSosAOImapAgent::SetActiveAndCompleteThis()
+    {
+    FUNC_LOG;
+    if ( !IsActive() )
+        {
+        SetActive();
+        }
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete(status, KErrNone);
+    }