PECengine/PresenceManager2/SrcCommon/CPEngAsyncOperation.cpp
changeset 0 094583676ce7
--- /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