diff -r 000000000000 -r 094583676ce7 wvuing/wvuieng/EngSrc/CCARequestMapper.cpp --- /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 +// ============================ 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 + 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 + 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 + 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