diff -r 000000000000 -r 094583676ce7 PECengine/PresenceManager2/SrcCommon/CPEngAsyncOperation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PECengine/PresenceManager2/SrcCommon/CPEngAsyncOperation.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,283 @@ +/* +* Copyright (c) 2004 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: Asynchronous operation base class. +* +*/ + +// INCLUDE FILES +#include "CPEngAsyncOperation.h" +#include "CPEngNWSessionSlotStorageProxy.h" +#include "CPEngSessionSlotId.h" +#include "MPEngAsyncOperationOwner.h" +#include "CPEngTransactionStatus.h" + + + +//LOCAL constants +namespace + { + //Panic + _LIT( KPEngAsyncOpPanic, "PEngAsyncOp" ); + + //Panic reasons + enum TPEngAsyncOpPanicReasons + { + EEngAsyncOpHasAlreadyOwner, + EEngAsyncOpAlreadyInUse + }; + + void PEngAsyncOpPanic( TPEngAsyncOpPanicReasons aPanicReason ) + { + User::Panic( KPEngAsyncOpPanic, aPanicReason ); + } + } + + + +// ================= MEMBER FUNCTIONS ======================= +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::CPEngAsyncOperation +// ----------------------------------------------------------------------------- +CPEngAsyncOperation::CPEngAsyncOperation( TInt aPriority, + RPEngManagerClient& aServer ) + : CActive( aPriority ), + iCancelling( EFalse ), + iTransactionServer( aServer ) + { + CActiveScheduler::Add( this ); + } + + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::~CPEngAsyncOperation() +// ----------------------------------------------------------------------------- +CPEngAsyncOperation::~CPEngAsyncOperation() + { + if ( iOperationOwner ) + { + iOperationOwner->HandleAsyncOperationDestruction( this ); + } + + delete iTransactionStatus; + delete iTransactionData; + + iTransactionClient.Close(); + } + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::BaseConstructL() +// ----------------------------------------------------------------------------- +void CPEngAsyncOperation::BaseConstructL( + CPEngNWSessionSlotStorageProxy& aUsedSlot ) + { + iTransactionStatus = CPEngTransactionStatus::NewL(); + HBufC8* sessSlotIdPkg = aUsedSlot.BaseId().PackLC(); + User::LeaveIfError( iTransactionClient.Connect( *sessSlotIdPkg, + aUsedSlot.AppId(), + iTransactionServer ) ); + + CleanupStack::PopAndDestroy( sessSlotIdPkg ); + } + + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::SetOwner() +// ----------------------------------------------------------------------------- +void CPEngAsyncOperation::SetOwner( MPEngAsyncOperationOwner& aOperationOwner ) + { + __ASSERT_ALWAYS( !iOperationOwner, + PEngAsyncOpPanic( EEngAsyncOpHasAlreadyOwner ) ); + + iOperationOwner = &aOperationOwner; + } + + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::CancelOpD() +// ----------------------------------------------------------------------------- +// +void CPEngAsyncOperation::CancelOpD() + { + if ( iCancelling ) + { + //Cancel already running... + //==>This call is coming from observer callback which + //was called from DoCancel(). Break the nesting here + return; + } + + iCancelling = ETrue; + CActive::Cancel(); + iCancelling = EFalse; + + delete this; + } + + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::InitTransaction() +// ----------------------------------------------------------------------------- +// +void CPEngAsyncOperation::InitTransaction( HBufC16* aTransactionData, + TInt aTransactionOperation ) + { + delete iTransactionData; + iTransactionData = aTransactionData; + iTransactionOperation = aTransactionOperation; + } + + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::IssueTransaction() +// ----------------------------------------------------------------------------- +// +void CPEngAsyncOperation::IssueTransaction() + { + __ASSERT_ALWAYS( !IsActive(), + PEngAsyncOpPanic( EEngAsyncOpAlreadyInUse ) ); + + TInt err = KErrNone; + if ( iTransactionData ) + { + err = iTransactionClient.UpdateData( iTransactionOperation, + *iTransactionData, + iStatus ); + } + else + { + err = iTransactionClient.UpdateData( iTransactionOperation, + KNullDesC, + iStatus ); + } + + + if ( err == KErrNone ) + { + SetActive(); + } + + else + { + iStatus = KRequestPending; + TRequestStatus *pS = &iStatus; + User::RequestComplete( pS, err ); + SetActive(); + } + } + + + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::DoCancel() +// ----------------------------------------------------------------------------- +void CPEngAsyncOperation::DoCancel() + { + iTransactionClient.CancelUpdateData(); + + iTransactionStatus->Reset(); + iTransactionStatus->SetStatus( KErrCancel ); + + DoHandleOpFailure( *iTransactionStatus, + iTransactionOperation ); + + DoNotifyObserver( *iTransactionStatus, + iTransactionOperation ); + } + + + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::RunL() +// ----------------------------------------------------------------------------- +void CPEngAsyncOperation::RunL() + { + if ( iStatus.Int() < KErrNone ) + { + //Operation failed somehow + User::Leave( iStatus.Int() ); + } + + if ( iStatus.Int() == KErrNone ) + { + //operation succesfull but no extra data available + iTransactionStatus->Reset(); + iTransactionStatus->SetStatus( KErrNone ); + } + + else + { + //Fetch & decode operation results + HBufC8* resultPkg = HBufC8::NewLC( iStatus.Int() ); + TPtr8 resultPkgPtr = resultPkg->Des(); + User::LeaveIfError( iTransactionClient.FetchLastRequestResult( resultPkgPtr ) ); + + iTransactionStatus->Reset(); + iTransactionStatus->UnpackResultsL( *resultPkg ); + CleanupStack::PopAndDestroy(); // resultPkg + } + + //Let derived class handle operation success + //-> try to decode data from transaction status + DoHandleOpSuccessL( *iTransactionStatus, iTransactionOperation ); + + + //And let derived class notify observer about operation completion + TPEngAsyncOpResult opStatus = DoNotifyObserver( *iTransactionStatus, + iTransactionOperation ); + + //Is transaction completed or should we wait for new round + if ( opStatus == EPEngAsyncOpCompleted ) + { + delete this; + } + else + { + iTransactionStatus->Reset(); + } + } + + +// ----------------------------------------------------------------------------- +// CPEngAsyncOperation::RunError() +// ----------------------------------------------------------------------------- +TInt CPEngAsyncOperation::RunError( TInt aError ) + { + iTransactionStatus->Reset(); + iTransactionStatus->SetStatus( aError ); + + DoHandleOpFailure( *iTransactionStatus, + iTransactionOperation ); + + + TPEngAsyncOpResult opStatus = DoNotifyObserver( *iTransactionStatus, + iTransactionOperation ); + + if ( opStatus == EPEngAsyncOpCompleted ) + { + delete this; + } + + return KErrNone; + } + + +// End of file