wvuing/wvuieng/EngSrc/CCARequestMapper.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/wvuieng/EngSrc/CCARequestMapper.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,719 @@
+/*
+* Copyright (c) 2002-2005 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:  This is the storage of asynchronous imps requests.
+*
+*/
+
+// INCLUDE FILES
+#include "CCARequestMapper.h"			// Own header
+#include "CCARequest.h"
+#include "ChatDebugPrint.h"
+#include "PrivateEngineDefinitions.h"
+
+#include "MCABackgroundTask.h"
+#include "MCABackgroundObserver.h"
+#include "CCABackgroundTask.h"
+
+#include <e32base.h>
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCARequestMapper* CCARequestMapper::NewL()
+    {
+    CCARequestMapper* self = new( ELeave ) CCARequestMapper;
+
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::~CCARequestMapper
+// Destructor
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CCARequestMapper::~CCARequestMapper()
+    {
+    CHAT_DP( D_CHAT_LIT( "RequestMapper destroying (%d requests pending)." ),
+             iRequestArray.Count() );
+
+    iRequestArray.ResetAndDestroy();
+    iRequestArray.Close();
+
+    iBackgroundTasks.ResetAndDestroy();
+    iBackgroundTasks.Close();
+    iBackgroundObservers.Reset();
+    iBackgroundObservers.Close();
+    iBackGroundTaskObserver.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::RegisterBackgroundTask
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCARequestMapper::RegisterBackgroundTask(
+    MCABackgroundTask* aBackgroundTask
+    , TCABackgroundTasks aTaskID
+    , TInt aSubTasks
+)
+    {
+    if ( !aBackgroundTask )
+        {
+        return KErrArgument;
+        }
+
+    TInt err( KErrNone );
+    TRAPD( leave, err = RegisterBackgroundTaskL(
+                            aBackgroundTask
+                            , aTaskID
+                            , aSubTasks
+                        ) );
+    switch ( leave )
+        {
+        case KErrNone:
+            {
+            return err;
+            }
+        case KErrNoMemory: // flowtrough
+        case KErrDiskFull:
+            {
+            CActiveScheduler::Current()->Error( leave );
+            return leave;
+            }
+        default:
+            {
+            return leave;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::RegisterBackgroundObserver
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCARequestMapper::RegisterBackgroundObserver(
+    MCABackgroundObserver* aBackgroundObserver
+    , TInt aTaskMask
+    , TInt aEventMask
+)
+    {
+    CHAT_DP( D_CHAT_LIT(
+                 "RequestMapper::RegisterBackgroundObserverL new observer %d %d" ),
+             aTaskMask, aEventMask );
+
+    TIdentityRelation<TBackgroundNotifier>
+    identity( TBackgroundNotifier::Identity );
+
+
+    TInt position ( iBackgroundObservers.Find( TBackgroundNotifier(
+                                                   aBackgroundObserver ), identity ) );
+
+    TInt err( KErrNone );
+    if ( position == KErrNotFound )
+        {
+        err = iBackgroundObservers.Append( TBackgroundNotifier(
+                                               aBackgroundObserver
+                                               , aTaskMask
+                                               , aEventMask
+                                           ) );
+        }
+    else
+        {
+        iBackgroundObservers[ position ].iTaskMask = aTaskMask;
+
+        iBackgroundObservers[ position ].iEventMask = aEventMask;
+
+        }
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::BackgroundTaskStatus
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCARequestMapper::BackgroundTaskStatus(
+    TCABackgroundTasks aTaskID
+)
+    {
+    CHAT_DP( D_CHAT_LIT( "CCARequestMapper::BackgroundTaskStatus() task %d" ),
+             aTaskID );
+
+    const TInt limit( iBackgroundTasks.Count() );
+    for ( TInt i( 0 ); i < limit; i++ )
+        {
+        CCABackgroundTask* task = iBackgroundTasks[ i ];
+
+        if ( task->TaskId() == aTaskID )
+            {
+            CHAT_DP( D_CHAT_LIT( "CCARequestMapper::BackgroundTaskStatus() task \
+                                 %d status:%d" )
+                     , aTaskID, task->TaskState() );
+            return task->TaskState();
+            }
+        }
+    return KErrNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::UnRegisterBackgroundObserver
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCARequestMapper::UnRegisterBackgroundObserver(
+    MCABackgroundObserver* aBackgroundObserver
+)
+    {
+    CHAT_DP_TXT( "RequestMapper::UnRegisterBackgroundObserver" );
+
+    TIdentityRelation<TBackgroundNotifier>
+    identity( TBackgroundNotifier::Identity );
+
+    TInt position ( iBackgroundObservers.Find( TBackgroundNotifier(
+                                                   aBackgroundObserver )
+                                               , identity ) );
+
+    if ( position == KErrNotFound )
+        {
+        return position;
+        }
+    else
+        {
+        iBackgroundObservers.Remove( position );
+        return KErrNone;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::HandleBackgroundTask
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCARequestMapper::HandleBackgroundTask(
+    MCABackgroundInterface::TCABackgroundTasks aTask )
+    {
+
+    TInt position( KErrNotFound );
+
+    TInt limit( iBackgroundTasks.Count() );
+    TInt index( 0 );
+
+    while ( index < limit && position == KErrNotFound )
+        {
+        if ( iBackgroundTasks[ index ]->TaskId() == aTask )
+            {
+            position = index;
+            }
+        index++;
+        }
+
+    __ASSERT_ALWAYS( position != KErrNotFound , User::Panic(
+                         KCAEnginePanicCategory, EBackgroundTaskNotFound ) );
+
+    if ( iBackgroundTasks[ position ]->TaskState() &
+         (
+             MCABackgroundInterface::ECancelled |
+             MCABackgroundInterface::EUnknown
+         ) )
+        {
+        //task cancelled nothing to do
+
+        return EFalse;
+        }
+    NotifyBackgroundObservers(
+        position,
+        EStarting,
+        iBackgroundTasks[ position ]->SubTasks()
+    );
+    TRAPD( leave , iBackgroundTasks[ position ]->ExecuteTaskL() );
+    CHAT_DP( D_CHAT_LIT( "CCARequestMapper::HandleBackgroundTask() task %d, \
+	                      subtask %d left with %d" ),
+             aTask, 0, leave );
+    if ( leave )
+        {
+        NotifyBackgroundObservers(
+            position,
+            MCABackgroundInterface::EFailed,
+            iBackgroundTasks[ position ]->SubTasks(),
+            leave
+        );
+        }
+    else
+        {
+        NotifyBackgroundObservers(
+            position,
+            MCABackgroundInterface::ECompleted,
+            iBackgroundTasks[ position ]->SubTasks()
+        );
+        }
+
+    NotifyBackgroundTaskObservers();
+
+    return iBackgroundTasks[ position ]->More();
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::HandleNetworkStateChange
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCARequestMapper::HandleNetworkStateChange( TNetworkState aState )
+    {
+    CHAT_DP( D_CHAT_LIT( "CCARequestMapper::HandleNetworkStateChange state %d" ),
+             aState );
+    if ( aState != ELoggedIn )
+        {
+        //Cancelling all penging request
+        CancelAllRequests();
+
+        //Cancelling all background task
+        TInt limit( iBackgroundTasks.Count() );
+        for ( TInt i( 0 ); i < limit; i++ )
+            {
+            CCABackgroundTask* task = iBackgroundTasks[ i ];
+            task->Cancel();
+
+            if ( task->TaskState() & ( MCABackgroundInterface::EIdleStarted
+                                       | MCABackgroundInterface::EStarting
+                                       | MCABackgroundInterface::EWaiting ) )
+                {
+                NotifyBackgroundObservers(
+                    i
+                    , MCABackgroundInterface::EUnknown
+                    , task->SubTasks()
+                );
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::CreateRequestL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CCARequest* CCARequestMapper::CreateRequestL( TInt aOpId,
+                                              TBool aWait,
+                                              TBool aDestroyAfterComplete,
+                                              TCallBack aCallBack )
+    {
+    CHAT_DP( D_CHAT_LIT( "RequestMapper::CreateRequestL (OpId: %d, Wait: %d, \
+	                      aDestroyAfterComplete: %d, aCallBack: %d)" ),
+             aOpId, aWait, aDestroyAfterComplete, aCallBack.iFunction );
+
+    CCARequest* request = CCARequest::NewL( aOpId,
+                                            aDestroyAfterComplete,
+                                            aCallBack );
+    request->SetRequestMapper( this );
+
+    TInt err( iRequestArray.Append( request ) );
+
+    if ( err != KErrNone )
+        {
+        CHAT_DP( D_CHAT_LIT( "RequestMapper::CreateRequestL failed with \
+		                      error code %d!!!" ), err );
+        delete request;
+        User::Leave( err );
+        }
+
+    if ( aWait )
+        {
+        CHAT_DP( D_CHAT_LIT( "Wait starting...request type is %d" ),
+                 request->RequestType() );
+
+        request->StartWait();
+        }
+
+    return request;
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::FindRequest
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+const CCARequest* CCARequestMapper::FindRequest( TInt aOpId )
+    {
+    return DoFindRequest( aOpId );
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::RemoveRequest
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCARequestMapper::RemoveRequest( CCARequest* aRequest )
+    {
+    TInt index( iRequestArray.Find( aRequest ) );
+    CHAT_DP( D_CHAT_LIT( "RequestMapper::RemoveRequest (Index: %d)" ), index );
+
+    if ( index != KErrNotFound )
+        {
+        delete aRequest;
+        iRequestArray.Remove( index );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::RemoveRequestAndLeaveIfErrorL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCARequestMapper::RemoveRequestAndLeaveIfErrorL( CCARequest* aRequest )
+    {
+    if ( aRequest )
+        {
+        TInt errorCode( aRequest->ErrorCode() );
+        RemoveRequest( aRequest );
+
+        User::LeaveIfError( errorCode );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::HandleRequest
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCARequestMapper::HandleRequest( TInt aOpId, TInt aErrorCode )
+    {
+    CHAT_DP( D_CHAT_LIT( "RequestMapper::HandleRequest (OpId: %d, Error: %d)" ),
+             aOpId, aErrorCode );
+
+    CCARequest* request = DoFindRequest( aOpId );
+
+    //signal OOM
+    if ( aErrorCode == KErrNoMemory || aErrorCode == KErrDiskFull )
+        {
+        CActiveScheduler::Current()->Error( aErrorCode );
+        }
+
+    // If we have the request...
+    if ( request )
+        {
+        // Set error code
+        request->SetErrorCode( aErrorCode );
+        // Call callback function if one is defined
+        request->ExecuteCallBackFunction();
+        // Stop wait if needed
+        request->StopWaitIfNeeded();
+        // Destroy object if marked so
+        if ( request->DestroyAfterComplete() )
+            {
+            RemoveRequest( request );
+            }
+        }
+    CHAT_DP_TXT( "RequestMapper::HandleRequest over" );
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::CancelAllRequests
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCARequestMapper::CancelAllRequests()
+    {
+    CHAT_DP( D_CHAT_LIT( "RequestMapper::CancelAllRequests (%d)" ),
+             iRequestArray.Count() );
+
+    CCARequest* request = NULL;
+
+    for ( TInt i( 0 ); i < iRequestArray.Count(); ++i )
+        {
+        request = iRequestArray[i];
+        request->SetErrorCode( EOperationCancelled );
+        request->StopWaitIfNeeded();
+        }
+
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::WaitCount
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCARequestMapper::WaitCount()
+    {
+    return iWaitCount;
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::ReportWaitStart
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCARequestMapper::ReportWaitStart()
+    {
+    iWaitCount++;
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::ReportWaitStop
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCARequestMapper::ReportWaitStop()
+    {
+    iWaitCount--;
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::CCARequestMapper
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CCARequestMapper::CCARequestMapper()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::DoFindRequest
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CCARequest* CCARequestMapper::DoFindRequest( TInt aOpId )
+    {
+    CHAT_DP_TXT( "CCARequestMapper::DoFindRequest" );
+    TInt indexCount( iRequestArray.Count() );
+
+    for ( TInt index( 0 ); index < indexCount; index ++ )
+        {
+        if ( iRequestArray[index]->IdMatches( aOpId ) )
+            {
+            CHAT_DP_TXT( "CCARequestMapper::DoFindRequest over +" );
+            return iRequestArray[index];
+            }
+        }
+    CHAT_DP_TXT( "CCARequestMapper::DoFindRequest over -" );
+    return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::NotifyBackgroundObservers
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCARequestMapper::NotifyBackgroundObservers(
+    TInt aTaskPosition,
+    TCABackgroundStatus aStatus,
+    TInt aSubTaskNumber,
+    TInt aLeaveCode
+)
+    {
+    CHAT_DP( D_CHAT_LIT( "CCARequestMapper::NotifyBackgroundObservers() \
+	                      %d %d %d %d" ),
+             aTaskPosition, aStatus, aSubTaskNumber, aLeaveCode );
+
+    TInt limit( iBackgroundObservers.Count() );
+    CCABackgroundTask* task = iBackgroundTasks[ aTaskPosition ];
+    task->SetTaskState( aStatus );
+
+    for ( TInt i( 0 ); i < limit; i++ )
+        {
+        if ( ( task->TaskId() & iBackgroundObservers[ i ].iTaskMask ) &&
+             ( aStatus & iBackgroundObservers[ i ].iEventMask ) )
+            {
+            iBackgroundObservers[ i ].iObserver->HandleBackgroundEvent(
+                task->TaskId()
+                , aStatus
+                , aSubTaskNumber
+                , aLeaveCode
+            );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCARequestMapper::RegisterBackgroundTaskL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCARequestMapper::RegisterBackgroundTaskL(
+    MCABackgroundTask* aBackgroundTask
+    , TCABackgroundTasks aTaskID
+    , TInt aSubTasks
+)
+    {
+
+    CCABackgroundTask* newTask = CCABackgroundTask::NewLC(
+                                     this
+                                     , aBackgroundTask
+                                     , aTaskID
+                                     , aSubTasks
+                                 );
+    TIdentityRelation<CCABackgroundTask>
+    identity( CCABackgroundTask::Identity );
+
+    TInt position ( iBackgroundTasks.Find( newTask, identity ) );
+
+    if ( position != KErrNotFound )
+        {
+        CCABackgroundTask* toRemove = iBackgroundTasks[ position ];
+        iBackgroundTasks.Remove( position );
+        delete toRemove;
+        }
+
+    TInt err( KErrNone );
+    err = iBackgroundTasks.Append( newTask );
+    if ( err )
+        {
+        CleanupStack::PopAndDestroy( newTask );
+        return err;
+        }
+    else
+        {
+        CleanupStack::Pop( newTask );
+        }
+
+    position = iBackgroundTasks.Count() - 1;
+
+    newTask->Start();
+
+    newTask->SetTaskState( MCABackgroundInterface::EIdleStarted );
+
+    NotifyBackgroundObservers(
+        position,
+        EIdleStarted,
+        newTask->SubTasks()
+    );
+    return err; //KErrNone
+    }
+
+// -----------------------------------------------------------------------------
+// TBackgroundNotifier::TBackgroundNotifier
+// constructor
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBackgroundNotifier::TBackgroundNotifier( MCABackgroundObserver* aObserver
+                                          , TInt aTaskMask
+                                          , TInt aEventMask
+                                        ) :
+        iObserver( aObserver )
+        , iTaskMask( aTaskMask )
+        , iEventMask( aEventMask )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// TBackgroundNotifier::Identity
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool TBackgroundNotifier::Identity( const TBackgroundNotifier& aA
+                                     , const TBackgroundNotifier& aB
+                                   )
+    {
+    return ( aA.iObserver == aB.iObserver );
+    }
+
+
+// -----------------------------------------------------------------------------
+// TBackgroundNotifier::IsBackgroundTaskPending
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+TBool CCARequestMapper::IsBackgroundTaskPending()
+    {
+    const TInt limit( iBackgroundTasks.Count() );
+
+    for ( TInt i( 0 ); i < limit; i++ )
+        {
+        CCABackgroundTask* task = iBackgroundTasks[ i ];
+
+        if ( task->TaskId() == EGroupFetch )
+            {
+
+            MCABackgroundInterface::TCABackgroundStatus taskState = task->TaskState();
+
+            if ( taskState == EIdleStarted || taskState == EStarting || taskState == EWaiting )
+                {
+
+                return ETrue;
+                }
+            }
+        }
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CCAEngine::RegisterGroupSyncObserver()
+// ---------------------------------------------------------
+//
+void CCARequestMapper::RegisterBackGroundTaskObserver( MCABackGroundTaskObserver* aObserver )
+    {
+    ASSERT( aObserver );
+    TInt status( iBackGroundTaskObserver.Find( aObserver ) );
+    if ( status == KErrNotFound )
+        {
+        status = iBackGroundTaskObserver.Append( aObserver ) ;
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAEngine::UnRegisterGroupSyncObserver()
+// ---------------------------------------------------------
+//
+void CCARequestMapper::UnRegisterBackGroundTaskObserver( MCABackGroundTaskObserver* aObserver )
+    {
+    ASSERT( aObserver );
+    const TInt status( iBackGroundTaskObserver.Find( aObserver ) );
+    if ( status != KErrNotFound )
+        {
+        iBackGroundTaskObserver.Remove( status );
+        iBackGroundTaskObserver.Compress();
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAEngine::NotifyGroupSyncObservers()
+// ---------------------------------------------------------
+//
+void CCARequestMapper::NotifyBackgroundTaskObservers()
+    {
+    TInt count = iBackGroundTaskObserver.Count();
+
+    for ( TInt i = 0; i < count; i++ )
+        {
+        TRAP_IGNORE ( iBackGroundTaskObserver[i]->HandleBackGroundTaskCompleteL( IsBackgroundTaskPending() ) );
+        }
+    }
+
+//  End of File