ncdengine/provider/client/src/ncdbaseoperationproxy.cpp
changeset 4 32704c33136d
equal deleted inserted replaced
-1:000000000000 4:32704c33136d
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <s32mem.h>
       
    20 
       
    21 #include "ncdbaseoperationproxy.h"
       
    22 #include "ncdoperationfunctionids.h"
       
    23 #include "ncdsendableprogress.h"
       
    24 #include "ncdsendable.h"
       
    25 #include "catalogsclientserver.h"
       
    26 #include "ncdoperationproxyremovehandler.h"
       
    27 #include "ncdnode.h"
       
    28 #include "ncdnodeproxy.h"
       
    29 #include "ncdqueryimpl.h"
       
    30 #include "catalogsconstants.h"
       
    31 #include "catalogsutils.h"
       
    32 #include "ncdnodemanagerproxy.h"
       
    33 #include "ncdnodeidentifier.h"
       
    34 #include "ncdexpirednode.h"
       
    35 #include "ncdutils.h"
       
    36 #include "ncdpurchasehistory.h"
       
    37 #include "ncdnodemetadataproxy.h"
       
    38 #include "ncdproviderproxy.h"
       
    39 #include "ncdpanics.h"
       
    40 #include "catalogsdebug.h"
       
    41 
       
    42 // ======== MEMBER FUNCTIONS ========
       
    43 
       
    44 // ---------------------------------------------------------------------------
       
    45 // From class MNcdOperation
       
    46 // ?implementation_description
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 
       
    50 MNcdOperation::TState CNcdBaseOperationProxy::DoOperationStateL() const
       
    51     {
       
    52     return iState;
       
    53     }
       
    54     
       
    55 // ---------------------------------------------------------------------------
       
    56 // From class MNcdOperation
       
    57 // ?implementation_description
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 void CNcdBaseOperationProxy::DoStartOperationL()
       
    61     {
       
    62     DLTRACEIN((""));
       
    63     
       
    64     if ( iState == MNcdOperation::EStateCancelled )
       
    65         {
       
    66         User::Leave( KErrCancel );
       
    67         }
       
    68     
       
    69     if ( iState != MNcdOperation::EStateStopped )
       
    70         {
       
    71         DLTRACE(("Already running"));
       
    72         // Operation is already running.
       
    73         //User::Leave( KErrInUse );
       
    74         return;
       
    75         }
       
    76     
       
    77     InitBuffersL( 0, 0 );
       
    78     
       
    79     ClientServerSession().SendAsyncAlloc( ENCDOperationFunctionStart,
       
    80         SendBuf8L(),
       
    81         iReceiveBuffer,
       
    82         Handle(),
       
    83         iStatus,
       
    84         0 );
       
    85     DLTRACE(("Setting active"));
       
    86     SetActive();
       
    87     DASSERT( iStatus.Int() == KRequestPending );
       
    88     SetState( MNcdOperation::EStateRunning );
       
    89     DLTRACEOUT((""));
       
    90     }
       
    91 
       
    92 
       
    93 // ---------------------------------------------------------------------------
       
    94 // From class MNcdOperation
       
    95 // ?implementation_description
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 void CNcdBaseOperationProxy::DoCancelOperation()
       
    99     {
       
   100     DLTRACEIN((""));
       
   101     if ( iState != MNcdOperation::EStateCancelled &&
       
   102         iState != MNcdOperation::EStateComplete )
       
   103         {
       
   104         DLTRACE(("Sending cancel message to server"));
       
   105 
       
   106         Cancel();
       
   107         
       
   108         // Send cancel message to server-side        
       
   109         TInt tmpNum( 0 );
       
   110         ClientServerSession().
       
   111             SendSync( ENCDOperationFunctionCancel,
       
   112                       KNullDesC8(),
       
   113                       tmpNum,
       
   114                       Handle() );     
       
   115         iState = MNcdOperation::EStateCancelled;
       
   116         
       
   117         
       
   118         DLTRACE(("Calling complete callback with KErrCancel"));
       
   119         CompleteCallback( KErrCancel );
       
   120         }
       
   121     }
       
   122 
       
   123 // ---------------------------------------------------------------------------
       
   124 // From class MNcdOperation
       
   125 // ?implementation_description
       
   126 // ---------------------------------------------------------------------------
       
   127 //
       
   128 TNcdProgress CNcdBaseOperationProxy::DoProgress() const
       
   129     {
       
   130     DLTRACEIN((""));
       
   131     TNcdProgress progress( iProgress.iProgress,
       
   132                            iProgress.iMaxProgress );
       
   133     return progress;
       
   134     }
       
   135 
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // From class MNcdOperation
       
   139 // Completes a query
       
   140 // ---------------------------------------------------------------------------
       
   141 //
       
   142 void CNcdBaseOperationProxy::DoCompleteQueryL( MNcdQuery& aQuery )
       
   143     {
       
   144     DLTRACEIN((""));
       
   145     DASSERT( static_cast<CNcdQuery&>(aQuery).Id() == iQuery->Id() );
       
   146     (void)aQuery; // to suppress compiler warning
       
   147     delete iSendBuffer;
       
   148     iSendBuffer = NULL;
       
   149     iSendBuffer = CBufFlat::NewL( KBufExpandSize );
       
   150     RBufWriteStream stream( *iSendBuffer );
       
   151     CleanupClosePushL( stream );
       
   152     iQuery->ExternalizeL( stream );
       
   153     iQuery->InternalRelease();
       
   154     iQuery = NULL;
       
   155     iSendPtr.Set(iSendBuffer->Ptr( 0 ) );    
       
   156     DLINFO(("buf length= %d", iSendPtr.Length()));
       
   157     
       
   158     delete iReceiveBuffer;
       
   159     iReceiveBuffer = NULL;
       
   160 
       
   161     ClientServerSession().SendAsyncAlloc( ENCDOperationFunctionQueryResponse,
       
   162                                      iSendPtr,
       
   163                                      iReceiveBuffer,
       
   164                                      Handle(),
       
   165                                      iStatus,
       
   166                                      0 );
       
   167     CleanupStack::PopAndDestroy( &stream );    
       
   168     SetActive();
       
   169     
       
   170     }
       
   171 
       
   172 // ---------------------------------------------------------------------------
       
   173 // From class MNcdOperation
       
   174 // ?implementation_description
       
   175 // ---------------------------------------------------------------------------
       
   176 //
       
   177 MNcdNode* CNcdBaseOperationProxy::DoNode()
       
   178     {
       
   179     if ( iNode )
       
   180         {
       
   181         // Increase the reference counter for the node if it exists.
       
   182         iNode->AddRef();        
       
   183         }
       
   184         
       
   185     return iNode;
       
   186     }
       
   187 
       
   188 // ---------------------------------------------------------------------------
       
   189 // ?description_if_needed
       
   190 // ---------------------------------------------------------------------------
       
   191 //
       
   192 CNcdBaseOperationProxy::CNcdBaseOperationProxy(
       
   193     MNcdClientLocalizer* aLocalizer ):
       
   194         iSendPtr( NULL, 0),
       
   195         iStringLocalizer( aLocalizer )
       
   196     {
       
   197     
       
   198     DLTRACEIN((""));
       
   199     }
       
   200 
       
   201 // ---------------------------------------------------------------------------
       
   202 // ?description_if_needed
       
   203 // ---------------------------------------------------------------------------
       
   204 //
       
   205 void CNcdBaseOperationProxy::ConstructL( MCatalogsClientServer& aSession,
       
   206     TInt aHandle,
       
   207     MNcdOperationProxyRemoveHandler* aRemoveHandler,
       
   208     CNcdNodeProxy* aNode,
       
   209     CNcdNodeManagerProxy* aNodeManager )
       
   210     {
       
   211     DLTRACEIN((""));    
       
   212     iSession = &aSession;
       
   213     iHandle = aHandle;
       
   214     iRemoveHandler = aRemoveHandler;
       
   215     iNode = aNode;
       
   216     iNodeManager = aNodeManager;
       
   217 
       
   218     if ( iNode != NULL )
       
   219         {
       
   220         // Because we own the node for a while, increase the internal
       
   221         // reference counter by one to be sure that is will be alive
       
   222         iNode->InternalAddRef();
       
   223         }
       
   224 
       
   225     // Because this is an active object, we need to inform
       
   226     // scheduler about it.    
       
   227     CActiveScheduler::Add( this );    
       
   228     }
       
   229 
       
   230 // ---------------------------------------------------------------------------
       
   231 // Destructor
       
   232 // ---------------------------------------------------------------------------
       
   233 //
       
   234 CNcdBaseOperationProxy::~CNcdBaseOperationProxy()
       
   235     {
       
   236     DLTRACEIN((""));   
       
   237 
       
   238     Cancel(); 
       
   239 
       
   240     // Release the server-side operation
       
   241     SendReleaseMessage();
       
   242     
       
   243     delete iReceiveBuffer;
       
   244     delete iSendBuffer;
       
   245     delete iSendHeapBuf8;        
       
   246         
       
   247     if ( iNode != NULL )
       
   248         {
       
   249         iNode->InternalRelease();
       
   250         }
       
   251         
       
   252     if ( iQuery != NULL )
       
   253         {
       
   254         iQuery->InternalRelease();
       
   255         }
       
   256     
       
   257     iNodeManager = NULL;  
       
   258     
       
   259     // NOTE: Operation classes MUST remove themselves from
       
   260     // the operation manager through the RemoveHandler
       
   261     DLTRACEOUT((""));
       
   262     }
       
   263 
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // ?implementation_description
       
   267 // ---------------------------------------------------------------------------
       
   268 //
       
   269 void CNcdBaseOperationProxy::HandleCompletedMessage(
       
   270     TNcdOperationMessageCompletionId aCompletionId,
       
   271     RReadStream& aReadStream,
       
   272     TInt aDataLength )
       
   273     {
       
   274     DLTRACEIN((_L("aCompletionId =%d, aDataLength =%d"), aCompletionId,
       
   275         aDataLength));
       
   276     
       
   277     TRAPD(err,
       
   278     CleanupClosePushL( aReadStream );
       
   279     switch ( aCompletionId )
       
   280         {
       
   281         case ENCDOperationMessageCompletionProgress:
       
   282             {
       
   283             DLTRACE(("Completion progress"));
       
   284             // Read progress info
       
   285             iProgress.InternalizeL( aReadStream );                        
       
   286             
       
   287             
       
   288             // Progress callback is last so that the op is resumed 
       
   289             // as soon as possible
       
   290             ProgressCallback();            
       
   291 
       
   292             SendContinueMessageL();            
       
   293             break;
       
   294             }
       
   295         case ENCDOperationMessageCompletionQuery:
       
   296             {
       
   297             DLTRACE(("Completion query"));
       
   298             // A call to complete query is needed after this to
       
   299             // continue operation.
       
   300             iState = MNcdOperation::EStateQuery;            
       
   301             DASSERT( ! iQuery );
       
   302             iQuery = CNcdQuery::NewL( aReadStream );
       
   303             iQuery->SetClientLocalizer( iStringLocalizer );
       
   304             if( iQuery->MessageTitle() == KNullDesC &&
       
   305                 iQuery->MessageBody() == KNullDesC && 
       
   306                 iQuery->ItemCount() < 1 )
       
   307                 {
       
   308                 DLTRACE(("No localizations for query without items, don't show"));
       
   309                 iQuery->SetResponseL( MNcdQuery::EAccepted );
       
   310                 DoCompleteQueryL( *iQuery );
       
   311                 }
       
   312             else
       
   313                 {
       
   314                 QueryReceivedCallback( iQuery );
       
   315                 }
       
   316             break;
       
   317             }
       
   318         case ENCDOperationMessageCompletionError:
       
   319             {
       
   320             DLTRACE(("Completion error: %d", iStatus.Int() ));
       
   321             iState = MNcdOperation::EStateComplete;
       
   322             CompleteCallback( iStatus.Int() );
       
   323             break;
       
   324             }
       
   325         case ENCDOperationMessageCompletionComplete:
       
   326             {
       
   327             DLTRACE(("Completion complete"));
       
   328             iState = MNcdOperation::EStateComplete;
       
   329             CompleteCallback( KErrNone );
       
   330             break;
       
   331             }
       
   332             
       
   333         case ENCDOperationMessageCompletionInit:
       
   334             {
       
   335             DLTRACE(("Completion init"));
       
   336             iState = MNcdOperation::EStateStopped;
       
   337             InitializationCallback( aReadStream, aDataLength );
       
   338             break;
       
   339             }
       
   340             
       
   341         case ENCDOperationMessageCompletionExpirationInfo:
       
   342             {
       
   343             DLTRACE(("ENCDOperationMessageCompletionExpirationInfo"));
       
   344             TInt nodeCount = aReadStream.ReadInt32L();
       
   345             RPointerArray<CNcdExpiredNode> expiredNodes;
       
   346             CleanupResetAndDestroyPushL( expiredNodes );
       
   347             for ( TInt i = 0 ; i < nodeCount ; i++ )
       
   348                 {
       
   349                 CNcdExpiredNode* expiredNode = CNcdExpiredNode::NewLC(
       
   350                     aReadStream );
       
   351                 DLINFO( (_L("Expired node: id=%S, ns=%S, force update=%d"),
       
   352                     &expiredNode->NodeIdentifier().NodeId(),
       
   353                     &expiredNode->NodeIdentifier().NodeNameSpace(),
       
   354                     expiredNode->ForceUpdate() ) );
       
   355                 DLINFO(( "Appending nodes." ));
       
   356                 expiredNodes.AppendL( expiredNode );
       
   357                 DLINFO(( "Popping expired one." ));
       
   358                 CleanupStack::Pop( expiredNode );
       
   359                 }
       
   360             // send expiration info to provider
       
   361             DLINFO(( "Send exp info." ));
       
   362             iNodeManager->HandleExpiredNodesL( expiredNodes );
       
   363             DLINFO(( "Pop & destroy expired nodes." ));
       
   364             CleanupStack::PopAndDestroy( &expiredNodes );
       
   365             DLINFO(( "Continue message" ));
       
   366             SendContinueMessageL();
       
   367             DLTRACE(("ENCDOperationMessageCompletionExpirationInfo done"));
       
   368             break;
       
   369             }
       
   370                 
       
   371         default:
       
   372             {
       
   373             // Unknown completion id -> corrupt data
       
   374             iState = MNcdOperation::EStateStopped;
       
   375             CompleteCallback( KErrCorrupt );
       
   376             }
       
   377         }
       
   378     
       
   379     CleanupStack::PopAndDestroy( &aReadStream );
       
   380     ); // TRAPD
       
   381     if ( err != KErrNone )
       
   382         {
       
   383         DLERROR(("Error %d! Calling CompleteCallback", err));
       
   384         CompleteCallback( err );
       
   385         }
       
   386     }
       
   387 
       
   388 // ---------------------------------------------------------------------------
       
   389 // ?implementation_description
       
   390 // ---------------------------------------------------------------------------
       
   391 //
       
   392 void CNcdBaseOperationProxy::SendContinueMessageL()
       
   393     {
       
   394     DLTRACEIN(("IsActive: %d", IsActive() ));
       
   395     DASSERT( iState != MNcdOperation::EStateCancelled );
       
   396     
       
   397     // Prevents continue message sending when the server's response to
       
   398     // an asyncronous message has not yet been received but some
       
   399     // synchronous operation wants to send a continue msg because it
       
   400     // thinks that there isn't any.
       
   401     // 
       
   402     // Basically this fixes NCDALTCI-369 where client-side crashed when a 
       
   403     // download was quickly paused and resumed and the server had just 
       
   404     // completed a progress message before the download was paused but
       
   405     // it got handled after the op was resumed again
       
   406     if ( !IsActive() ) 
       
   407         {            
       
   408         InitBuffersL( 0, 0 );
       
   409         ClientServerSession().SendAsyncAlloc( 
       
   410             ENCDOperationFunctionContinue,
       
   411             SendBuf8L(),
       
   412             iReceiveBuffer,
       
   413             Handle(),
       
   414             iStatus,
       
   415             0 );
       
   416         DLTRACE(("Setting active"));
       
   417         SetActive();        
       
   418         }
       
   419     }
       
   420     
       
   421 
       
   422 // ---------------------------------------------------------------------------
       
   423 // Sends a message that releases the operation on the server side
       
   424 // ---------------------------------------------------------------------------
       
   425 //    
       
   426 void CNcdBaseOperationProxy::SendReleaseMessage()
       
   427     {
       
   428     DLTRACEIN((""));
       
   429     
       
   430     TInt tmpNum( 0 );
       
   431     ClientServerSession().
       
   432         SendSync( ENCDOperationFunctionRelease,                  
       
   433                   KNullDesC8(),
       
   434                   tmpNum,
       
   435                   Handle() );     
       
   436                   
       
   437     }
       
   438 
       
   439 // ---------------------------------------------------------------------------
       
   440 // ?implementation_description
       
   441 // ---------------------------------------------------------------------------
       
   442 //
       
   443 void CNcdBaseOperationProxy::InitBuffersL( TInt aSendSize, TInt /*aReceiveSize*/)
       
   444     {
       
   445     DLTRACEIN((""));
       
   446     
       
   447     // Make sure that the send buffer exists.
       
   448     TRAPD( sendError, SendBuf8L() );
       
   449     if( sendError == KErrNotFound )
       
   450         {
       
   451         SetSendBuf8( HBufC8::NewL( aSendSize ) );
       
   452         }
       
   453     
       
   454     delete iReceiveBuffer;
       
   455     iReceiveBuffer = NULL;
       
   456     }
       
   457 
       
   458 
       
   459 // ---------------------------------------------------------------------------
       
   460 // Initializes the operation
       
   461 // ---------------------------------------------------------------------------
       
   462 //
       
   463 void CNcdBaseOperationProxy::InitializeOperationL()
       
   464     {
       
   465     DLTRACEIN((""));
       
   466     
       
   467     // Get the initialization buffer from the implementing class    
       
   468     HBufC8* initBuf = CreateInitializationBufferL();    
       
   469 
       
   470     SetSendBuf8( initBuf );
       
   471 
       
   472     delete iReceiveBuffer;
       
   473     iReceiveBuffer = NULL;
       
   474 
       
   475     DLTRACE(("Sending init message"));
       
   476     // Initialization is done synchronously
       
   477     User::LeaveIfError( ClientServerSession().SendSyncAlloc( 
       
   478         ENCDOperationFunctionInit,
       
   479         SendBuf8L(),
       
   480         iReceiveBuffer,
       
   481         Handle(),
       
   482         0 ) );
       
   483 
       
   484     DLTRACE(("Received response, &iReceiveBuffer: %X, length: %d", iReceiveBuffer,
       
   485         iReceiveBuffer->Length() ));
       
   486     if ( ! iReceiveBuffer || iReceiveBuffer->Length() < sizeof(TInt) )
       
   487         {
       
   488         DLTRACE(("Corrupt data"));
       
   489         // Corrupt data.
       
   490         iState = MNcdOperation::EStateStopped;
       
   491         User::Leave( KErrCorrupt );
       
   492         }
       
   493     
       
   494     DLTRACE(("Reading completion id"));    
       
   495     // Let's read the completion id
       
   496     TInt dataLength( iReceiveBuffer->Length() );
       
   497     RDesReadStream desReadStream( *iReceiveBuffer );
       
   498     CleanupClosePushL( desReadStream );
       
   499     
       
   500     TNcdOperationMessageCompletionId completionId = 
       
   501         static_cast<TNcdOperationMessageCompletionId>( 
       
   502         desReadStream.ReadInt32L() );
       
   503     
       
   504     DASSERT( completionId == ENCDOperationMessageCompletionInit );
       
   505 
       
   506     CleanupStack::Pop(); // RDesReadStream
       
   507     
       
   508     DLTRACE(("Handling completed message"));
       
   509     // Handler functions will take care of the rest.
       
   510     HandleCompletedMessage( completionId, desReadStream,
       
   511         dataLength );
       
   512     DLTRACEOUT((""));
       
   513     }
       
   514 
       
   515 
       
   516 // ---------------------------------------------------------------------------
       
   517 // Empty implementation
       
   518 // ---------------------------------------------------------------------------
       
   519 //
       
   520 HBufC8* CNcdBaseOperationProxy::CreateInitializationBufferL()
       
   521     {
       
   522     return HBufC8::NewL( 0 );
       
   523     }
       
   524 
       
   525 
       
   526 // ---------------------------------------------------------------------------
       
   527 // Empty implementation
       
   528 // ---------------------------------------------------------------------------
       
   529 //
       
   530 void CNcdBaseOperationProxy::InitializationCallback( 
       
   531     RReadStream& /* aReadStream */, TInt aDataLength )
       
   532     {
       
   533     DLTRACEIN( ( "Data length: %d", aDataLength ) );
       
   534     (void)aDataLength;   // to suppress compiler warning
       
   535     }
       
   536 
       
   537 
       
   538 // ---------------------------------------------------------------------------
       
   539 // ?implementation_description
       
   540 // ---------------------------------------------------------------------------
       
   541 //
       
   542 void CNcdBaseOperationProxy::SetState( MNcdOperation::TState aState )
       
   543     {
       
   544     iState = aState;
       
   545     }
       
   546     
       
   547     
       
   548 // ---------------------------------------------------------------------------
       
   549 // ?implementation_description
       
   550 // ---------------------------------------------------------------------------
       
   551 //
       
   552 TNcdSendableProgress& CNcdBaseOperationProxy::SendableProgress()
       
   553     {
       
   554     return iProgress;
       
   555     }
       
   556 
       
   557 
       
   558 CNcdNodeManagerProxy* CNcdBaseOperationProxy::NodeManager() const
       
   559     {
       
   560     return iNodeManager;
       
   561     }
       
   562 
       
   563 CNcdNodeProxy* CNcdBaseOperationProxy::NodeProxy() const
       
   564     {
       
   565     return iNode;
       
   566     }
       
   567 
       
   568 
       
   569 // ---------------------------------------------------------------------------
       
   570 // UpdateOperationInfoToPurchaseHistoryL
       
   571 // ---------------------------------------------------------------------------
       
   572 //
       
   573 void CNcdBaseOperationProxy::UpdateOperationInfoToPurchaseHistoryL( TInt aErrorCode )
       
   574     {
       
   575     DLTRACEIN((""));
       
   576     
       
   577     CNcdNodeProxy* node( NodeProxy() );
       
   578     NCD_ASSERT_ALWAYS( node, ENcdPanicNoData );
       
   579         
       
   580     CNcdNodeMetadataProxy* metadata( node->Metadata() );
       
   581     NCD_ASSERT_ALWAYS( metadata, ENcdPanicNoData );
       
   582 
       
   583     // Notice, that release must be called, when history is not used anymore.
       
   584     MNcdPurchaseHistory* purchaseHistory( 
       
   585         NodeManager()->Provider().PurchaseHistoryL() );
       
   586     NCD_ASSERT_ALWAYS( purchaseHistory, ENcdPanicNoData );
       
   587     
       
   588     CleanupReleasePushL( *purchaseHistory );
       
   589 
       
   590     CNcdNodeIdentifier& identifier =
       
   591         metadata->Identifier();
       
   592 
       
   593 
       
   594     DLINFO(("Create filter"));
       
   595     // Create the filter. So, we will get
       
   596     // the purchase history details we want.
       
   597     CNcdPurchaseHistoryFilter* filter =
       
   598         CNcdPurchaseHistoryFilter::NewLC();
       
   599 
       
   600     // Add client Uids to the filter
       
   601     RArray< TUid > clientUids;
       
   602     CleanupClosePushL( clientUids );
       
   603     clientUids.AppendL( identifier.ClientUid() );
       
   604     filter->SetClientUids( clientUids.Array() );
       
   605     CleanupStack::PopAndDestroy( &clientUids );
       
   606     
       
   607     // Add other filter values
       
   608     filter->SetNamespaceL( identifier.NodeNameSpace() );
       
   609     filter->SetEntityIdL( identifier.NodeId() );
       
   610 
       
   611 
       
   612     // Get the ids. So, we can next get all the corresponding
       
   613     // details and update them into the purchase history.
       
   614     RArray< TUint > ids =
       
   615         purchaseHistory->PurchaseIdsL( *filter );
       
   616 
       
   617     CleanupStack::PopAndDestroy( filter );
       
   618 
       
   619     CleanupClosePushL( ids );
       
   620     
       
   621     // Get all the details and add history items into the
       
   622     // array.    
       
   623     if ( ids.Count() > 0 )
       
   624         {
       
   625         DLINFO(("At least one purchase id existed: %d", ids.Count() ));
       
   626         
       
   627         // Operations always use the newest details. So, use it here also.
       
   628         // We do not want to load icons. So, use EFalse.
       
   629             
       
   630         CNcdPurchaseDetails* details(
       
   631             purchaseHistory->PurchaseDetailsL( ids[ 0 ] , EFalse ) );
       
   632             
       
   633         if ( details != NULL )
       
   634             {
       
   635             CleanupStack::PushL( details );
       
   636             
       
   637             DLINFO(("Details was found"));
       
   638                             
       
   639             // Set the error code and the lates operation time
       
   640             details->SetLastOperationErrorCode( aErrorCode );
       
   641             details->SetLastUniversalOperationTime();
       
   642                 
       
   643             // Save purchase details into the purchase history.
       
   644             // This will replace the old detail.
       
   645             // But, do not replace old icon, because we did not load it
       
   646             // for the details above.
       
   647             purchaseHistory->SavePurchaseL( *details, EFalse );
       
   648             
       
   649             CleanupStack::PopAndDestroy( details );
       
   650             details = NULL;            
       
   651             }
       
   652         }
       
   653     
       
   654     CleanupStack::PopAndDestroy( &ids );  
       
   655     
       
   656     CleanupStack::PopAndDestroy( purchaseHistory );  
       
   657     
       
   658     DLTRACEOUT((""));
       
   659     }
       
   660     
       
   661     
       
   662 // ---------------------------------------------------------------------------
       
   663 // From CActive
       
   664 // ?implementation_description
       
   665 // ---------------------------------------------------------------------------
       
   666 //
       
   667 void CNcdBaseOperationProxy::RunL()
       
   668     {
       
   669     DLTRACEIN(("iReceiveBuffer=%X, status: %d, state: %d", 
       
   670         iReceiveBuffer, iStatus.Int(), iState ));
       
   671 
       
   672     
       
   673     if ( iStatus.Int() == KErrCancel ) 
       
   674         {
       
   675         DLINFO(("The operation was cancelled by engine"));
       
   676         // Do not complete with KErrCancel since it is used when the operation
       
   677         // is cancelled by UI. These cases has to be distinguished somehow.
       
   678         iState = MNcdOperation::EStateCancelled;
       
   679         CompleteCallback( KErrAbort );
       
   680         return;
       
   681         }
       
   682     else if ( iState == MNcdOperation::EStateCancelled )
       
   683         {
       
   684         DLINFO(("The operation has already been cancelled"));
       
   685         // Ignore message
       
   686         return;
       
   687         }
       
   688     
       
   689     if ( ! iReceiveBuffer || iReceiveBuffer->Length() < sizeof(TInt) )
       
   690         {
       
   691         DLTRACE(("corrupt data"));
       
   692         // Corrupt data.
       
   693         iState = MNcdOperation::EStateStopped;
       
   694         // error callback: KErrCorrupt
       
   695         CompleteCallback( KErrCorrupt );
       
   696         return;
       
   697         }
       
   698 
       
   699     // Let's read the completion id
       
   700     TInt dataLength( iReceiveBuffer->Length() );
       
   701     RDesReadStream desReadStream( *iReceiveBuffer );
       
   702     TNcdOperationMessageCompletionId completionId = ENCDOperationMessageCompletionError;
       
   703     TRAPD( err, completionId =
       
   704         static_cast<TNcdOperationMessageCompletionId>
       
   705         ( desReadStream.ReadInt32L() ) );
       
   706     if ( err != KErrNone )
       
   707         {
       
   708         DLTRACE(("corrupt"));
       
   709         CompleteCallback( KErrCorrupt );
       
   710         return;
       
   711         }
       
   712     DLTRACE(("id read"));
       
   713     // Handler functions will take care of the rest.
       
   714     HandleCompletedMessage( completionId, desReadStream,
       
   715         dataLength );
       
   716     DLTRACEOUT((""));
       
   717     }
       
   718     
       
   719 // ---------------------------------------------------------------------------
       
   720 // From CActive
       
   721 // ?implementation_description
       
   722 // ---------------------------------------------------------------------------
       
   723 //
       
   724 void CNcdBaseOperationProxy::DoCancel()
       
   725     {
       
   726     DLTRACEIN((""));
       
   727     
       
   728     DLTRACE(("Cancel async requests"));
       
   729     ClientServerSession().AsyncMessageSenderDown( iStatus ); 
       
   730     }
       
   731     
       
   732 
       
   733 // ---------------------------------------------------------------------------
       
   734 // From CActive
       
   735 // ---------------------------------------------------------------------------
       
   736 //
       
   737 TInt CNcdBaseOperationProxy::RunError( TInt aError )
       
   738     {
       
   739     DLTRACEIN(("Error: %d in RunL()", aError ));
       
   740     return aError;
       
   741     }
       
   742     
       
   743 MCatalogsClientServer& CNcdBaseOperationProxy::ClientServerSession() const
       
   744     {
       
   745     DLTRACEIN((""));    
       
   746     return *iSession;
       
   747     }    
       
   748     
       
   749 TInt CNcdBaseOperationProxy::Handle() const
       
   750     {
       
   751     return iHandle;
       
   752     }
       
   753 
       
   754 
       
   755 const TDesC8& CNcdBaseOperationProxy::SendBuf8L()
       
   756     {
       
   757     if( iSendHeapBuf8 == NULL )
       
   758         {
       
   759         User::Leave( KErrNotFound );
       
   760         }
       
   761         
       
   762     return *iSendHeapBuf8;
       
   763     }
       
   764 
       
   765     
       
   766 void CNcdBaseOperationProxy::SetSendBuf8( HBufC8* aBuffer )
       
   767     {
       
   768     delete iSendHeapBuf8;
       
   769     iSendHeapBuf8 = aBuffer;
       
   770     }